该题解的思路是先找到最短无序连续子数组的候选区间 [l, r],然后再扩展该区间直到满足条件。具体步骤如下:
1. 从左到右扫描数组,找到第一个破坏升序的位置 l;
2. 从右到左扫描数组,找到最后一个破坏升序的位置 r;
3. 如果没找到 l 和 r,说明数组本身有序,直接返回 0;
4. 在 [l, r] 区间内找到最小值 Min 和最大值 Max;
5. 从 l 开始向左扩展,直到找到第一个小于 Min 的位置,更新 l;
6. 从 r 开始向右扩展,直到找到第一个大于 Max 的位置,更新 r;
7. 返回 r - l + 1 作为最短无序连续子数组的长度。
时间复杂度: O(n)
空间复杂度: O(1)
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
n = len(nums)
# 从左到右扫描,找第一个破坏升序的位置
l,r = -1, -1
for i in range(1, n):
if nums[i-1] > nums[i]:
l = i-1
break
# 从右到左扫描,找最后一个破坏升序的位置
for i in range(n-1, 0, -1):
if nums[i-1] > nums[i]:
r = i
break
# 数组本身有序,直接返回 0
if l < 0:
return 0
# 在 [l, r] 区间内找最小值和最大值
Min, Max = min(nums[l:r+1]), max(nums[l:r+1])
# 从 l 向左扩展,直到找到小于 Min 的位置
while l > 0 and Min < nums[l-1]:
l -= 1
# 从 r 向右扩展,直到找到大于 Max 的位置
while r < n-1 and Max > nums[r+1]:
r += 1
# 返回最短无序连续子数组的长度
return r - l + 1