這個問題和“最多能完成排序的塊”相似,但給定數組中的元素可以重複,輸入數組最大長度爲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;
}
};
/**
* 完結散花
*/