具体思路:
单调栈,还是不清楚什么时候用;
1.单调栈思路:
维护一个递增单调栈;
当遇到比栈顶元素大的,直接入栈,否则弹栈到栈顶元素小于该元素,或者空栈为止;
最后栈内元素个数即为块个数;
理解:
栈内代表多段以栈元素结尾的序列;
考虑:
2,3,1
这种情况;
则遇到1的时候,应该进行区间合并,因为1必须出现在2的前面;
因此合并区间为1,2,3,栈内只剩下3;
当多段情况:
2,3,1,5,6,4
这种情况前三个栈内必定为3;
因为4大于3,因此无法动1,2,3这个序列,不会进行区间合并;
考虑:
2,3,1,5,6,0;
因为0小于3,因此应该将0合并进区间3内,因此最后栈内只剩下6;
2.找规律:
对于前i个最大元素maxn,排序后必须出现在相应的位置;
如果i=maxn,则说明排序后maxn必须在i的位置,因此可以切一刀;
并且不会有小于maxn的元素在i以后;
具体代码:
单调栈:
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) {
stack<int>st;
for(int i=0;i<arr.size();i++){
if(st.empty()||arr[i]>st.top()){
st.push(arr[i]);
continue;
}
int maxn=st.top();
while(!st.empty()&&st.top()>arr[i]){
st.pop();
}
st.push(maxn);
}
return st.size();
}
};
找规律:
class Solution {
public:
int maxChunksToSorted(vector<int>& arr) {
int mx = -1, ans = 0, n = arr.size();
for (int i = 0; i < n; i++) {
mx = max(mx, arr[i]);
if (mx == i) {
mx = -1;
ans++;
}
}
return ans;
}
};