581. 最短无序连续子数组『简单』

题目来源于力扣(LeetCode

一、题目

581. 最短无序连续子数组

题目相关标签:数组

注意:

  1. 输入的数组长度范围在 [1, 10,000]。
  2. 输入的数组可能包含重复元素 ,所以升序的意思是<=。

二、解题思路

  1. 遍历两次 nums 数组

  2. 第一遍正序,遍历时,通过变量 high 记录下数组最后的一位小于前面一位元素的元素所在索引(即导致数组非递增,直接影响数组排序)

  3. 再一遍倒序,遍历时,通过变量 low 记录下数组最后的一位大于后面一位元素的元素所在索引(即导致数组非递增,直接影响数组排序)

  4. 结果 = 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);
}
posted @ 2020-05-25 00:05  知音12138  阅读(243)  评论(0编辑  收藏  举报