类似前缀和的 left min 和 right max,在求解买卖股票的最佳时机、递增的三元子序列比较有效
334. 递增的三元子序列
难度中等
给你一个整数数组 nums ,判断这个数组中是否存在长度为 3 的递增子序列。
如果存在这样的三元组下标 (i, j, k) 且满足 i < j < k ,使得 nums[i] < nums[j] < nums[k] ,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [1,2,3,4,5] 输出:true 解释:任何 i < j < k 的三元组都满足题意
示例 2:
输入:nums = [5,4,3,2,1] 输出:false 解释:不存在满足题意的三元组
示例 3:
输入:nums = [2,1,5,0,4,6] 输出:true 解释:三元组 (3, 4, 5) 满足题意,因为 nums[3] == 0 < nums[4] == 4 < nums[5] == 6
用dp做的话 n2复杂度,会用例超时:
dp[i] 表示第i个数小的元素的个数。 转移方程 if(nums[j] < nums[i]) dp[i] = max(dp[i],dp[j]+1) 如果直接两层for就超时了,最后一个测试用例过不去/。 链接:https://leetcode.cn/problems/increasing-triplet-subsequence/solution/dai-ma-jie-de-xiao-bai-javac-tan-xin-don-85ai/
类似前缀和的 left min 和 right max,用空间换时间。
class Solution:
def increasingTriplet(self, nums: List[int]) -> bool:
n = len(nums)
min_vals = [0] * n # left min
max_vals = [0] * n # right max
min_vals[0] = nums[0]
max_vals[n-1] = nums[n-1]
for i in range(1, n):
min_vals[i] = min(min_vals[i-1], nums[i])
max_vals[n-1-i] = max(max_vals[n-i], nums[n-1-i])
for i in range(n):
if min_vals[i] < nums[i] < max_vals[i]:
return True
return False
另外还有一种技巧的解法,如下:
class Solution:
def increasingTriplet(self, nums) -> bool:
# ref: https://leetcode.cn/problems/increasing-triplet-subsequence/solution/c-xian-xing-shi-jian-fu-za-du-xiang-xi-jie-xi-da-b/
n = len(nums)
small, mid = float('inf'), float('inf')
for i in range(n):
t = nums[i]
if t <= small:
small = t
elif t <= mid:
mid = t
elif t > mid:
return True
return False
121. 买卖股票的最佳时机
难度简单
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入:prices = [7,6,4,3,1] 输出:0 解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
和上面那个题都可以使用一样的思路做!!!

浙公网安备 33010602011771号