581. 最短无序连续子数组

161 阅读2分钟

这是我参与8月更文挑战的第N天,活动详情查看:8月更文挑战

581. 最短无序连续子数组

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

请你找出符合题意的 最短 子数组,并输出它的长度。

示例 1:

输入:nums = [2,6,4,8,10,9,15] 输出:5 解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。 示例 2:

输入:nums = [1,2,3,4] 输出:0 示例 3:

输入:nums = [1] 输出:0

解题思路

因为其中一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。

说明只有中间这个子数组是乱序的,前面一部分和后面一部分都是递增的。

  • [0, l-1],这个部分是数组的前部分,这个部分是已经排序好的结果,说明这个部分最大数就在l-1,并且这个部分所有的数都是小于后面两个部分的所有数

  • [l, r],这个部分就是我们要求的子数组,这部分是已经乱序的

  • [r+1, n-1],这个部分是数组的后部分,这个部分同样也是排序好的结果,其中最小的数下标为r+1,并且这个部分全部的数都要大于前面两个部分的数

因此我们可以维护一个从左到右的最大值和一个从右到左的最小值,最大值在前面和后面的递增数组中,都是正常递增的,但是在中间的乱序数组中,大值就会出现在小值的左边,当出现这种情况时,就说明了当前元素是在乱序数组当中的,对于最小值也是同样的道理

代码

class Solution {
    public int findUnsortedSubarray(int[] nums) {


        int min=Integer.MAX_VALUE,max=Integer.MIN_VALUE;
        int n=nums.length;     int l=-1,r=-1;
        for (int i=0;i<n;i++)
        {
            if (max>nums[i])
            {
                r=i;
            }else {
                max=nums[i];
            }
            if (min<nums[n-i-1])
            {
                l=n-i-1;
            }else {
                min=nums[n-i-1];
            }

        }
        return r==-1?0:r-l+1;
    }
}