LeetCode每日一题(581. Shortest Unsorted Continuous Subarray)

本文介绍了一个算法问题,涉及找到给定整数数组中逆序排列的最短连续子数组,通过正向和反向扫描优化到O(n)时间复杂度。通过实例和代码实现展示了如何利用前缀和与后缀和来定位违反规则的元素。

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

Example 1:

Input: nums = [2,6,4,8,10,9,15]
Output: 5

Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.

Example 2:

Input: nums = [1,2,3,4]
Output: 0

Example 3:

Input: nums = [1]
Output: 0

Constraints:

  • 1 <= nums.length <= 104
  • -105 <= nums[i] <= 105

Follow up: Can you solve it in O(n) time complexity?


一开始觉得这题挺简单, 结果被它生生折磨了一下午。
最终的思路是分别正向和反向的遍历数组,各找出第一个违反规则的元素, 并记录下它们的下标, 最终两个下标的差值就是需要重新排序的最短连续子数组。
详细点说就是, 从左向右, 如果某一元素大于其左侧所有元素的最大值,我们就可以认为这个元素违反了排序规则, 从右向左, 如果某一元素小于其右侧所有元素的最小值, 我们就可以认为这个元素违反了排序规则。


impl Solution {
    pub fn find_unsorted_subarray(nums: Vec<i32>) -> i32 {
        let prefix_sum: Vec<bool> = nums
            .iter()
            .scan(i32::MIN, |max, v| {
                *max = *max.max(&mut v.clone());
                Some(v < max)
            })
            .collect();
        let mut rev_prefix_sum: Vec<bool> = nums
            .iter()
            .rev()
            .scan(i32::MAX, |min, v| {
                *min = *min.min(&mut v.clone());
                Some(v > min)
            })
            .collect();
        rev_prefix_sum.reverse();
        if let Some(left) = rev_prefix_sum.into_iter().position(|v| v) {
            if let Some(right) = prefix_sum.into_iter().rposition(|v| v) {
                return (right - left + 1) as i32;
            }
            return 0;
        }
        0
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值