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
提示:
1 <= nums.length <= 104-105 <= nums[i] <= 105
进阶:你可以设计一个时间复杂度为 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