581. 最短无序连续子数组 - medium
给你一个整数数组 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)
的解决方案吗?
这个复杂度在于排序,排序后的比较复杂度在 O(n),
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
s = sorted(nums)
l = 0
while l < len(nums) and s[l] == nums[l]:
l += 1
if l == len(nums):
return 0
r = len(nums) - 1
while r >= 0 and s[r] == nums[r]:
r -= 1
return r - l + 1
从左往右遍历,寻找左边界 l
。使用栈记录保存过的 index,如果当前值小于栈顶元素,则弹出栈顶元素,并记录最小 idx,即为左边界。
同理从右往左遍历,找到右边界 r
。如果 r
<= l
,则说明已经有序。否则就是 r - l + 1
。
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
a = []
l, r = len(nums), 0
i = 0
while i < len(nums):
while a and nums[a[-1]] > nums[i]:
l = min(l, a.pop())
a.append(i)
i += 1
del a[:]
j = len(nums) - 1
while j >= 0:
while a and nums[a[-1]] < nums[j]:
r = max(r, a.pop())
a.append(j)
j -= 1
return 0 if r <= l else r - l + 1