LeetCodeDiary

A Diary for solving LeetCode problems

View on GitHub

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

提示:

进阶:你可以设计一个时间复杂度为 O(n) 的解决方案吗?

数组 中等

代码

1. 排序后查找不一样的数字位置

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        if n <= 1:
            return 0
        nums_s = sorted(nums)
        for i in range(n):
            if nums[i] != nums_s[i]:
                break
        j = 0
        for j in range(n-1, i , -1):
            if nums[j] != nums_s[j]:
                break
        return j - i + 1 if j else 0

2. 双指针

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        maxn, right = float("-inf"), -1
        minn, left = float("inf"), -1
        # 可以将nums分为A、B、C三段,其中B是无序的,A、C是有序的
        for i in range(n):
            if maxn > nums[i]:
                right = i # 最后一个更新的right就是B段的右边界
            else:
                maxn = nums[i]
            
            if minn < nums[n - i - 1]: # 倒序遍历
                left = n - i - 1 # 最后一个更新的left就是B段的左边界
            else:
                minn = nums[n - i - 1]
        
        return 0 if right == -1 else right - left + 1