比较难数组类的左右扫描法,须记住
思路:
同时从前往后和从后往前遍历,分别得到排序数组的右边界和左边界;
寻找右边界:从前往后遍历的过程中,用max记录遍历过的最大值,如果max大于当前的nums[i],说明nums[i]的位置不正确,应该属于需要排序的数组,因此将右边界更新为i,然后更新max;这样最终可以找到需要排序的数组的右边界,右边界之后的元素都大于max;
寻找左边界:从后往前遍历的过程中,用min记录遍历过的最小值,如果min小于当前的nums[j],说明nums[j]的位置不正确,应该属于需要排序的数组,因此将左边界更新为j,然后更新min;这样最终可以找到需要排序的数组的左边界,左边界之前的元素都小于min;
(从前往后遍历和从后往前遍历两个过程可以分两次循环完成,也可以放一起完成,这样的话就有:j=len-i-1)
class Solution {
public int findUnsortedSubarray(int[] nums) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
int n = nums.length;
// end 取-1保证数组有序时保证 end - start + 1 = 0
int start = 0, end = -1;
for (int i = 0; i < n; ++i){
//从左往右同时扫,找最大值
max = Math.max(max, nums[i]);
//从右往左同时扫,找最小值
min = Math.min(min, nums[n - 1 -i]);
//如果最大值大于当前值(需要排序),则更新end
if (max > nums[i]) end = i;
//如果最小值小当前值
//(最小值本来在前面的,跑后面去了需要排序),则更新start
if (min < nums[n - 1 - i]) start = n - 1 - i;
}
return end - start + 1;
}
}