LeetCode 581 Shortest Unsorted Continuous Subarray 题解

本文详细解析了LeetCode581题“最短无序连续子数组”的两种解法,一种是通过排序对比,另一种是寻找不满足条件的数字,后者时间复杂度为O(n),空间复杂度为O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

LeetCode 581 Shortest Unsorted Continuous Subarray 题解

题意

给定一个数组,找出一个最短的子序列使其满足,只将这个子序列重新排序即可使整个数组有序(升序)。输出这个最短子序列的长度。

思路

一 排序对比

比较容易想到的是将数组排序后与原数组对比。比如样例:

未排序 [2, 6, 4, 8, 10, 9, 15]
排序后 [2, 4, 6, 8, 9, 10, 15]
          ^            ^

很容就能得到结果。复杂度即为排序的复杂度O(logn)。

代码:

int findUnsortedSubarray(vector<int> &nums) {
    vector<int> nums_cp(nums);
    sort(nums.begin(), nums.end());
    const int sz = nums.size();
    int st = sz, ed = sz - 1;
    for (int i = 0; i < sz; i++) {
        if (nums[i] != nums_cp[i]) {
            st = i;
            break;
        }
    }
    for (int i = sz - 1; i >= 0; i--) {
        if (nums[i] != nums_cp[i]) {
            ed = i;
            break;
        }
    }
    return ed - st + 1;
}

二 寻找不满足条件的数字

对于一个从小到大排列的数组(长度为n)来说,容易得到如下条件:第i个数一定是0~i中最大的数,是i~n中最小的数。因此只需找到不满足上述条件的第一个和最后一个数即可:

  • 从后往前寻找下标最小的不满足 i个数是i~n中最小的数 的元素;

  • 从前往后寻找下标最大的不满足 i个数是0~i中最大的数 的元素;

代码如下:

int findUnsortedSubarray(vector<int> &nums) {
    const int sz = nums.size();
    int st = 0, ed = -1;
    int maxval = nums[0], minval = nums[sz - 1];
    for (int i = 1; i < sz; i++) {
        maxval = max(maxval, nums[i]);
        minval = min(minval, nums[sz - i - 1]);
        if (nums[i] < maxval)
            ed = i;
        if (nums[sz - i - 1] > minval)
            st = sz - i - 1;
    }
    return ed - st + 1;
}

总结

第二种方法时间复杂度为O(n),空间复杂度为O(1),只需在遍历同时求最小值与最大值,不断更新开始位置和结束位置即可得到答案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值