Leetcode 中级: 递增的三元子序列
有一个整数数组 nums
,判断这个数组中是否存在长度为 3 的递增子序列。
详细版:如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k
,使得 nums[i] < nums[j] < nums[k]
,返回 true ;否则,返回 false。
这种题啊,咱就是说整出来的解老是超时
就算告诉我用贪心策略,我也找不到那个最佳解的思路
所以干脆背一背得了,记一个笔记加深一下印象
思想
- 用一个
index
顺着数组搜索 - 记录当前最小值
s
和【排在最小值后面的】次小值m
- 如果当前值
num[index]
满足:num[index] < s
: 更新ss < num[index] < m
: 更新mnum[index] > s
: 返回True
举个例子
nums = [5, 2, 3, 1, 6]
第一步:初始化s = 5
第二步:找到一个比 s 更小的数 2,更新 s = 2
- 更新的后果是解空间得到扩大,因为2相对5来说有更大的找到解的可能
第三步:找到一个比 s 大的值3, 初始化 m = 3
第四步:找到一个比 s 更小的值1,更新 s = 1
- 更新的后果的依旧是解空间变大
- 而且不影响之前的 s = 2 噢, 因为既然 m = 3 了就说明在 3 之前有比 3 更小的
- 所以之后我们如果找到比 m = 3更大的值,还是可以直接return True
第四步:找到一个比 m 大的值 5 return True
为什么
- 先说
m
,它是【“排在s后面”】的次小值,也就是说:- 一定是先有
s
了,在后续搜索中找到比s
更大的数,才会创建一个m
- 所以
m
前面肯定存在一个比它更小的值 - 所以一旦在
m
后面找到一个大于它的值,递增三元序列马上成立
- 一定是先有
s
记录了最小值,也就是说:- 在搜索中只要遇到了比
s
小的就马上更新,更新的意义在于使解空间变大
- 在搜索中只要遇到了比
代码
def increasingTriplet(nums):
if len(nums) < 3:
# 如果长度没有到3,直接pass掉
return False
s = nums[0]
m = 2 ** 31 - 1
for index in range(1, len(nums)):
if nums[index] < s:
s = nums[index]
if nums[index] < m and nums[index] > s:
m = nums[index]
if nums[index] > m:
return True
return False