(思維)768. 最多能完成排序的塊 II

這個問題和“最多能完成排序的塊”相似,但給定數組中的元素可以重複,輸入數組最大長度爲2000,其中的元素最大爲10**8。

arr是一個可能包含重複元素的整數數組,我們將這個數組分割成幾個“塊”,並將這些塊分別進行排序。之後再連接起來,使得連接的結果和按升序排序後的原數組相同。

我們最多能將數組分成多少塊?

示例 1:

輸入: arr = [5,4,3,2,1]
輸出: 1
解釋:
將數組分成2塊或者更多塊,都無法得到所需的結果。
例如,分成 [5, 4], [3, 2, 1] 的結果是 [4, 5, 1, 2, 3],這不是有序的數組。 
示例 2:

輸入: arr = [2,1,3,4,4]
輸出: 4
解釋:
我們可以把它分成兩塊,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的塊數。 
注意:

arr的長度在[1, 2000]之間。
arr[i]的大小在[0, 10**8]之間。

題解:1、從後向前維護一個遞減的數組 b;

           2、用一個變量維護前 i 個數的最大值:maxx;

           3、判斷是否可以分成一個塊,情況判斷:

              (1)、當遍歷到數組尾部時,看作最後一個塊;

              (2)、當b[i] 與 b[i+1] 之間不同時,意味着a[i]在當前最小;

                           (原數組):    a  [3,1,3,3,2,4]

                           (遞增數組):b  [1,1,2,2,2,4]

              (3)、噹噹前最大值maxx等於b[i] (最小值)時; 

                           [0,3,0,3,2]     =>  2          [[0],[3,0,3,2]]    (這種情況當時少考慮了,wa了幾發)

                           [2,2,2,2,2]   =>    5          [[2],[2],[2],[2],[2]]

class Solution {
public:

    int maxChunksToSorted(vector<int>& a) {
        int len=a.size();
        vector<int>b;
        for(int i=0;i<len;i++) b.push_back(a[i]);
        
        for(int i=len-2;i>=0;i--)
            b[i]=min(b[i],b[i+1]);

        int maxx=a[0],p=0,ans=0;       //  p 維護的是當前塊的首位置
        for(int i=0;i<len;i++){
            if((i+1)==len||b[i]!=b[i+1]||maxx==b[i]){
                if(maxx!=b[i]){
                    if((i+1)==len||maxx<=b[i+1]){
                        ans++;
                        p=i+1;
                        maxx=(i+1)==len?-1:a[i+1];
                    }
                }
                else{
                    ans+=(i-p+1);
                    p=i+1;
                    maxx=(i+1)==len?-1:a[i+1];
                }
            }
            else maxx=max(maxx,a[i]);
        }
        return ans;
    }
};

/**
 *  完結散花
 */

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章