题目描述
arr
是一个可能包含重复元素的整数数组,我们将这个数组分割成几个“块”,并将这些块分别进行排序。之后再连接起来,使得连接的结果和按升序排序后的原数组相同。我们最多能将数组分成多少块?
输入: arr = [2,1,3,4,4]
输出: 4
解释:
我们可以把它分成两块,例如 [2, 1], [3, 4, 4]。
然而,分成 [2, 1], [3], [4], [4] 可以得到最多的块数。
解题思路
京东笔试题《合唱队》,单调栈解决。
- 贪心解法:只有对于某个位置,其左边(包括该数本身)的最大值不大于位置右侧的最小值,在该处就可以分段。
- 辅助栈解法:直接看代码就好。(如何想到的不太好理解,推荐另两种解法)
- 哈希表法:对序列A来说,如果知道其排序后的序列B。然后将序列A与序列B对比,容易分析出各个块。那么,块,满足两个特点:
- 块的位置和长度,在序列A和序列B中,相同。
- 块中的数字,在序列A和序列B中,相同,但顺序可能不同。(哈希表可以用
==
比较)
参考代码
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) {
stack<int> s;
for(auto &x:arr){
if(s.empty()||x>=s.top()){
s.push(x);
}else{
auto top = s.top();//保留栈顶最大值
s.pop();
while(!s.empty()&&x<s.top()){
//小的话,一直pop
s.pop();
}
s.push(top);
}
}
return s.size();
}
};