581. 最短无序连续子数组『简单』
题目来源于力扣(LeetCode)
一、题目
题目相关标签:数组
注意:
- 输入的数组长度范围在 [1, 10,000]。
- 输入的数组可能包含重复元素 ,所以升序的意思是<=。
二、解题思路
-
遍历两次 nums 数组
-
第一遍正序,遍历时,通过变量 high 记录下数组最后的一位小于前面一位元素的元素所在索引(即导致数组非递增,直接影响数组排序)
-
再一遍倒序,遍历时,通过变量 low 记录下数组最后的一位大于后面一位元素的元素所在索引(即导致数组非递增,直接影响数组排序)
-
结果 = high - low + 1 的长度
三、代码实现
public static int findUnsortedSubarray(int[] nums) {
// 排除特殊情况:长度为 0 时结果为 0
if (nums.length < 1) {
return 0;
}
// 变量 low 记录最前的一位小于后面元素的数字所在的索引位
int low = -1;
// 变量 high 记录最后的一位大于前面元素的数字所在的索引位
int high = -1;
// 令左侧最大值为数组第一位
int leftMax = nums[0];
// 令右侧最小值为数组最后一位
int rightMin = nums[nums.length - 1];
// 从前往后遍历,找到破坏排序的最后一位
for (int i = 1; i < nums.length; i++) {
if (nums[i] >= leftMax) {
leftMax = nums[i];
} else {
// 当前遍历元素小于前一位元素时,导致数组非递增排序
high = i;
}
}
// high 的值未更改时,数组是非递减排序
if (high == -1) {
return 0;
}
// 从后往前遍历,找到破坏排序的较大数
for (int i = nums.length - 2; i >= 0; i--) {
if (nums[i] <= rightMin) {
rightMin = nums[i];
} else {
// 当前遍历元素大于后一位元素时,导致数组非递增排序
low = i;
}
}
// 两个破坏排序的索引 + 1 = 序列的长度
return high - low + 1;
}
四、执行用时
五、部分测试用例
public static void main(String[] args) {
int[] nums = {2, 6, 4, 8, 10, 9, 15}; // output:5
// int[] nums = {2, 6, 5, 5, 5, 7, 15}; // output:4
int result = findUnsortedSubarray(nums);
System.out.println(result);
}