理论基础
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心。
455.分发饼干
result和j变化一致,可以去除一个
python
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
# 分配能满足孩子胃口的最小饼干。胃口排序,饼干也排序
g.sort()
s.sort()
# 遍历饼干,如果当前饼干满足不了当前最小孩子的胃口,肯定也满足不了后续的孩子,饼干继续循环
# 如果当前饼干满足了当前孩子的胃口,则当前饼干给当前孩子吃,结果+1,孩子胃口也向后遍历一个
j = 0 # 胃口索引
result = 0
for i in s:
if j < len(g) and g[j] <= i:
result += 1
j += 1
return result
376. 摆动序列
这道题可以使用贪心,也可以使用动态规划。这道题对我来说挺难,还需要继续思考
使用贪心需要考虑情况较多
python
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
if len(nums) <= 1:
return len(nums) # 如果数组长度为0或1,则返回数组长度
preDiff = 0 # 前一对元素的差值
result = 1 # 记录峰值的个数,初始为1(默认最右边的元素被视为峰值)
for i in range(len(nums) - 1):
curDiff = nums[i + 1] - nums[i] # 计算下一个元素与当前元素的差值
# 如果遇到一个峰值
if (preDiff <= 0 and curDiff > 0) or (preDiff >= 0 and curDiff < 0):
result += 1 # 峰值个数加1
preDiff = curDiff # 注意这里,只在摆动变化的时候更新preDiff
return result # 返回最长摆动子序列的长度
使用动态规划
python
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
dp = [[0, 0] for _ in range(len(nums))] # 创建二维dp数组,用于记录摆动序列的最大长度
dp[0][0] = dp[0][1] = 1 # 初始条件,序列中的第一个元素默认为峰值,最小长度为1
for i in range(1, len(nums)):
dp[i][0] = dp[i][1] = 1 # 初始化当前位置的dp值为1
for j in range(i):
if nums[j] > nums[i]:
dp[i][1] = max(dp[i][1], dp[j][0] + 1) # 如果前一个数比当前数大,可以形成一个上升峰值,更新dp[i][1]
for j in range(i):
if nums[j] < nums[i]:
dp[i][0] = max(dp[i][0], dp[j][1] + 1) # 如果前一个数比当前数小,可以形成一个下降峰值,更新dp[i][0]
return max(dp[-1][0], dp[-1][1]) # 返回最大的摆动序列长度
53. 最大子序和
本题可以用贪心,也可以用动态规划
贪心
python
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
result = float("-inf")
count = 0
for num in nums:
count += num
result = max(count, result)
if count < 0:
count = 0
return result