定个小目标之刷LeetCode热题(29)

发布于:2024-06-24 ⋅ 阅读:(65) ⋅ 点赞:(0)

581. 最短无序连续子数组

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。请你找出符合题意的 最短 子数组,并输出它的长度。

示例 1:

输入:nums = [2,6,4,8,10,9,15]

输出:5

解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

今天刷的是这道题,一次遍历找出无序连续子数组的左右边界即可,简单说下思路,首先我们要搞清楚这个无序连续子数组的左右边界有什么特征,比如示例1中无序连续子数组是[6, 4, 8, 10, 9],仔细观察会发现6,4是降序,10,9也是降序,在一个升序数组中这都是异常的,由此可知这个无序连续子数组的左右边界肯定是降序的(对于一个升序数组来说),所以先从左往右遍历数组,然后维护一个max和end,max表示最大的数字,end表示出现降序的情况,即当nums[i - 1] > nums[i]时,更新 end = i,这样我们就可以找到无序连续子数组的右边界了,那么左边界如何寻找呢,我们可以从右往左遍历,这样就成了在一个降序数组中寻找无序连续子数组的右边界问题,同理维护一个min和begin,min表示最小的数字,begin表示出现升序的情况,即当nums[i] > nums[i + 1]时,更新begin = i,最后无序连续子数组的长度就是end - begin + 1。

文字有点多,主要是为了加深自己的印象,代码如下

class Solution {
    public int findUnsortedSubarray(int[] nums) {
        int length = nums.length;
        if (length == 0 || length == 1)
            return 0;
        int min = nums[length - 1];
        int max = nums[0];
        int begin = 0, end = -1;
        for (int i = 0; i < length; i++) {
            // 从左往右遍历维护max,正常情况nums[length - 1]是最大的
            if (nums[i] >= max) {
                max = nums[i];
            } else {
                // 出现了降序,记录其下标
                end = i;
            }
            // 从右往左遍历维护min,正常情况nums[0]是最小的
            if (nums[length - 1 - i] <= min) {
                min = nums[length - 1 - i];
            } else {
                // 出现了升序,记录其下标
                begin = length - 1 - i;
            }
        }
        return end - begin + 1;
    }
}

题目链接:题单 - 力扣(LeetCode)全球极客挚爱的技术成长平台


网站公告

今日签到

点亮在社区的每一天
去签到