一次遍历方法:
/**
* 一次遍历
* 正常排序(1 2 3 4 5): 左边所有元素的最大值(2) <= 每个元素(例如3) <= 右边所有元素的最小值(4)
* 求解: 2 6 8 10 4 9 15
* 其中: 从左到右 9是最后一个小于 (左边所有元素最大值)的
* 从右到左 6是最后一个大于 (右边所有元素最小值)的
* 故解为求:
* 从左到右遍历, 记录当前遍历数的最大值, 最后一个小于最大值的即 需要倒置数组的右边索引
* 从右到左遍历, 记录当前遍历数的最小值, 最后一个大于最小值的即 需要倒置数组的左边索引
*/
public int findUnsortedSubarray(int[] nums) {
int length = nums.length;
int leftDiff = -1;
int rightDiff = -1;
//最大值是顺序遍历使用的(求需排序数组的右边索引rightDiff), 也可以取Integer.MIN_VALUE
int max = nums[0];
//最小值是倒序遍历使用的(求需排序数组的左边索引leftDiff), 也可以取Integer.MAX_VALUE
int min = nums[length - 1];
for (int i = 0; i < length; i++) {
//顺序执行, 判断 当前值是否小于 已遍历的最大值, 是的话属于需排序的数组元素, 替换rightDiff; 否就更新最大值
if (nums[i] < max){
rightDiff = i;
} else {
max = nums[i];
}
//倒序执行, 判断 当前值是否大于 已遍历的最小值, 是的话属于需排序的数组元素, 替换leftDiff; 否就更新最小值
int index = length - 1 - i;
if (nums[index] > min){
leftDiff = index;
} else {
min = nums[index];
}
}
return leftDiff != -1 ? rightDiff - leftDiff + 1 : 0;
}