方法1
思考过程:右侧不包含比当前最大值更小的值,当前即可为一个chunk—》》》当前最大值,右侧最小值;
对于数组[2,1,3,4,4],对于index=i,i右边如果没有小于当前最大值,则chunk数+1;
2,1,3最大为3,右边最小为4,因此右边不存在比前三个数更小的数了,换言之,前三个数包揽了 前三小, 可以单独为一个chunk;
public int maxChunksToSorted(int[] arr) {
int n=arr.length;
int[] leftMax=new int[n];
int[] rightMin=new int[n];
int res=0;
leftMax[0]=arr[0];
for(int i=1;i<n;i++){
leftMax[i]=Math.max(leftMax[i-1],arr[i]);
}
rightMin[0]=arr[n-1];
for(int i=n-2;i>=0;i--){
rightMin[i]=Math.min(rightMin[i+1],arr[i]);
}
for(int i=0;i<n-1;i++){
if(leftMax[i]<=rightMin[i+1])res++;
}
return res+1;
}
方法2
思考过程:如果当前数值 右侧存在比当前最大值 小的数a,则向前查找,直到找到一个b<a,则b之前为已知若干个chunk,由于较小数a的存在,此时b到a直接缩为一个chunk,且记录当前最大值,以备继续搜索后续较小的值。
正常情况,是递增的,如果存在一个拐点数据x,小于前者,那么找到x所在的位置,期间比x大的数均不能单独为一个chunk。
这个过程中,有一个逐步插入递增数据,当遇到较小值,有回滚的操作,寻找比x小的数值。不难想到,用stack对数据进行保存。
栈顶为当前最大值,每次回滚弹出不符合的chunk,即后面存在较小值,前面较大值 均不能为一个chunk。
public int maxChunksToSorted(int[] arr) {
int n = arr.length;
int max=Integer.MIN_VALUE;
Deque<Integer> dq=new LinkedList<>();
for(int i=0;i<n;i++){
max=dq.isEmpty()?arr[i]:Math.max(arr[i],dq.peek());
while(!dq.isEmpty()&&dq.peek()>arr[i])dq.pop();
dq.push(max);
}
return dq.size();
}
#相关题目
Next Greater Element II (a very basic one)
Largest Rectangle in Histogram(almost the same as this problem)
Maximal Rectangle(please do this problem after you solve the above one)
Trapping Rain Water (challenge)
Remove Duplicate Letters(challenge)
Remove K Digits
Create Maximum Number
132 Pattern(challenge, instead of focusing on the elements in the stack, this problem focuses on the elements poped from the monotone stack)
sliding window maximum(challenge, monotone queue)
Max Chunks To Make Sorted II