(leetcode)581、最短无序连续子数组

在这里插入图片描述

前后扫描法(时间复杂度 O(n)

【找到从前往后最后一个比前半部分当前最大值小的】

【找到从后往前最后一个比后半部分当前最小值大的】

  • 寻找左右边界的核心关键: 逆序对!
  • 对于完全符合条件的序列(即完全有序),应该是没有逆序对存在的!
  • 所以本题的无序序列的左右边界
  • 其实就是**左边界的前面的元素与其后所有元素严格顺序; 右边界后面的元素,与前面所有元素严格顺序**
    • 比如: 2| 6, 4, 8, 10, 9| 15
    • 其中 2后面所有元素严格顺序!
    • 15前面所有元素严格顺序!
    • 所以寻找左右边界的流程就是: 2| 6, 4, 8, 10, 9| 15
    • 从左往右(------->)
      • 先将第一个值设为当前max
        • nums[i] >= max,构成顺序对,更新 max = nums[i]
          • 比如: 26 此时max ==2 , nums[i] == 6 , 由于 6 > 2 , 所以更新max =6
        • nums[i] < max,构成了逆序对,更新无序右边界 right = i
          • 比如 : 64 此时max ==6nums[i] == 4 , 由于 4 < 6 , 所以更新右边界 right = 2
    • 从右往左: (<-------)
      • 先将最后一个值设为min
        • nums[i] <= min更新 min
        • nums[i] > min ,构成逆序对,更新无序左边界 left = i
// 代码中,将上述两个遍历过程合成了一个遍历过程
public int findUnsortedSubarray(int[] nums) {

        int len = nums.length;
        //  max :表示当前遍历的元素的最大值  从前往后
        //  min :表示当前遍历元素的最小值    从后往前
        int max = nums[0];
        int min = nums[len - 1];

        int left = 0, right = -1;
      
        for (int i = 0; i < len; i++) {
            // 右边界
            if (max <= nums[i]) {
                max = nums[i];
            } else {
                right = i;
            }

            // 左边界
            if (min >= nums[len - i - 1]) {
                min = nums[len - i - 1];
            } else {
                left = len - i - 1;
            }
        }
        return right - left + 1;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值