题目描述
从数组中找一个连续子数字,对子数组升序的时候,数组就是升序的。
求最短的子数组的长度?
f1排序+双指针 |
基本分析
- 如果排序后怎么找?左边第一个不等的点和右边第一个不等的点
代码
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
nums_sorted = sorted(nums)
n = len(nums)
l, r = 0, n-1
while l <= r and nums[l] == nums_sorted[l]:
l += 1
while r >= l and nums[r] == nums_sorted[r]:
r -= 1
return r - l + 1
总结
- 这里为啥用 <=, 不是 < ? 待明确
f2-双指针一次遍历 |
基本分析
- k遍历的区间?l,r
- 指针移动的方向?i从l到0,j从r到n-1
- 每次枚举k,什么时候需要更新i或者j?j位置的值比左边的最小小或者比右边的最大大
- 如果需要维护,怎么维护?一直往左或者往右找,找到第一个<=nums[k]的值,或者第一个>=nums[k]的值
- 越界的情况怎么处理?i到头给-inf,j到头给inf,这样判断的时候都会满足
- 结果怎么计算?区分相等或者不等的情况
代码
class Solution:
def findUnsortedSubarray(self, nums: List[int]) -> int:
n = len(nums)
i, j = 0, n-1
while i < j and nums[i] <= nums[i+1]:
i += 1
while i < j and nums[j] >= nums[j-1]:
j -= 1
# 这里找到的i和j都是满足单调条件的
l, r = i, j
# 最开始是1增结尾,3增开始
curmin, curmax = nums[i], nums[j]
# 为什么l是满足条件的,为啥要从l遍历?可能nums[l] > max
for k in range(l, r+1):
# 如果当前值比左边的小值小,小值的位置不保
if nums[k] < curmin:
while i >= 0 and nums[i] > nums[k]:
i -= 1
# 出来以后i可能是0,可能是找到了满足nums[i] <= nums[k]的索引
if i < 0:
# 足够小了,不用再比了
curmin = -inf
else:
# 否则更新当前小值
curmin = nums[i]
if nums[k] > curmax:
while j <= n-1 and nums[j] < nums[k]:
j += 1
# 找到的合适的点可能是结尾,可能是真的有
if j > n-1:
# 别找了
curmax = inf
else:
curmax = nums[j]
# 遍历完以后,可能ij就是一个点,也可能不是
if i == j:
return 0
else:
return (j-1) - (i+1) + 1
总结
- 可能可以用单调栈处理,需要考虑下