贪心
(1)121. 买卖股票的最佳时机
第 i 天卖出的最大利润,即在前面最低价的时候买入
py
class Solution:
def maxProfit(self, prices: List[int]) -> int:
min_price = prices[0]
ans = 0
for price in prices:
ans = max(ans, price - min_price)
min_price = min(min_price, price)
return ans
(2)152. 乘积最大子数组 ------ 美团一面
py
class Solution:
def maxProduct(self, nums: List[int]) -> int:
n = len(nums)
f_max = [0] * n
f_min = [0] * n
f_max[0] = f_min[0] = nums[0]
for i in range(1, n):
x = nums[i]
f_max[i] = max(f_max[i-1] * x, f_min[i-1] * x, x)
f_min[i] = min(f_max[i-1] * x, f_min[i-1] * x, x)
return max(f_max)
(3)55. 跳跃游戏

max_idx[i]
表示nums[0 : max_idx]
所有元素中可以到达的最远位置- 所以只需逐个遍历每个位置, 判断从之前的位置开始跳能否到达该位置
py
class Solution:
def canJump(self, nums: List[int]) -> bool:
# max_idx[i] 表示 nums[0 : max_idx] 所有元素中可以到达的最远位置
# 所以只需逐个遍历每个位置, 判断从之前的位置开始跳能否到达该位置
max_idx = 0
for i,v in enumerate(nums):
if i > max_idx:
return False
max_idx = max(max_idx, i + nums[i])
return True
(4)45. 跳跃游戏 II

只在无法继续走的时候才建桥,且建的是最远的桥,这是所有方案中最优的。
只遍历到 n-2 因为我们的边界 cur_right,在遍历到 n-2 后,更新后的 cur_right 一定是 > n-2的,所以一定大于等于 n-1
py
class Solution:
def jump(self, nums: List[int]) -> int:
# 只在无法继续走的时候才建桥,且建的是最远的桥,这是所有方案中最优的。
ans = 0
cur_right = 0 # 已构造桥的最远端
next_right = 0 # 下一座桥的最远端
for i in range(len(nums) - 1):
next_right = max(next_right, i + nums[i])
if cur_right == i:
cur_right = next_right
ans += 1
return ans
(5)763. 划分字母区间

「同一字母最多出现在一个片段中」
意味着,一个片段若要包含字母 a,那么所有的字母 a 都必须在这个片段中
利用合并区间的思想,s = a b a b c b a c a d e f e g d e h i j h k l i j
- a出现的区间为 [0,8]
- b出现的区间为 [1,5]
- c 出现的区间为 [4,7]
结合<45. 跳跃游戏 II>的思路,
- 区间右端点相当于当前点能到达的最远位置,
- 如果这个最远的位置都被前面最远区间的最远位置包含住了
- 那么这两个区间需要合并为一个区间
当 end = i
时,说明从 strat 到 当前位置 i 中的所有元素的最远区间就是当前位置
所以把当前位置划分为一个区间
py
class Solution:
def partitionLabels(self, s: str) -> List[int]:
last = {v:i for i,v in enumerate(s)} # 每个字母最后出现的位置
start = end = 0
ans = []
for i,v in enumerate(s):
end = max(end, last[v])
if end == i:
ans.append(end-start+1)
start = i + 1
return ans