1. 贪心算法理论基础
贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
1.1 什么时候用贪心
贪心没有固定的套路,当一道题可以由局部最优推算出整体最优的时候,就可以用贪心。
1.2 贪心的一般解题步骤
贪心算法一般分为如下四步:
- 将问题分解为若干个子问题
- 找出适合的贪心策略
- 求解每一个子问题的最优解
- 将局部最优解堆叠成全局最优解
步骤有些琐碎,实际做题不会这么详细的去构思
2. 练习题
第一题
Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie.
Each child
ihas a greed factorg[i], which is the minimum size of a cookie that the child will be content with; and each cookiejhas a sizes[j]. Ifs[j] >= g[i], we can assign the cookiejto the childi, and the childiwill be content. Your goal is to maximize the number of your content children and output the maximum number.
大饼干既能满足贪婪高的小孩,也能满足贪婪低的小孩,但是小饼干只能满足贪婪低的小孩,因此要优先把大的分给贪婪高的小孩,避免浪费大饼干。
所以要从后向前来遍历饼干和小孩。
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort()
s.sort()
index = len(s) - 1
result = 0
for i in range(len(g)-1, -1, -1):
if index >= 0 and s[index] >= g[i]:
result += 1
index -= 1
return result
第二题
A wiggle sequence is a sequence where the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with one element and a sequence with two non-equal elements are trivially wiggle sequences.
- For example,
[1, 7, 4, 9, 2, 5]is a wiggle sequence because the differences(6, -3, 5, -7, 3)alternate between positive and negative.- In contrast,
[1, 4, 7, 2, 5]and[1, 7, 4, 5, 5]are not wiggle sequences. The first is not because its first two differences are positive, and the second is not because its last difference is zero.A subsequence is obtained by deleting some elements (possibly zero) from the original sequence, leaving the remaining elements in their original order.
Given an integer array
nums, return the length of the longest wiggle subsequence ofnums.
乍一看很麻烦,因为又要剔除无关元素,又要求出符合条件的最大长度。但实际上不需要对数组进行什么in place的操作,只是统计一下符合要求的长度即可。
可以用两个变量:curDiff 和 preDiff来计算当前数组中元素与前后数的差值。
class Solution:
def wiggleMaxLength(self, nums: List[int]) -> int:
if len(nums)<= 1:
return len(nums)
curDiff = 0 # current
preDiff = 0 # previous
result = 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
preDiff = curDiff
return result
第三题
Given an integer array
nums, find the subarray with the largest sum, and return its sum.
先设置一个无穷小的数当起点,然后不断累加列表中的数,同时进行比较,遇到比较大的数就给了result,当累加完这次,数值变成负的就重置为0,避免对结果造成影响。
class Solution:
def maxSubArray(self, nums: List[int]) -> int:
result = float('-inf')
count = 0
for i in range(len(nums)):
count += nums[i]
if count > result:
result = count
if count <= 0:
count = 0
return result
本文介绍了贪心算法的理论基础,包括其本质是选择局部最优以达全局最优,以及适用场景和一般解题步骤。同时给出了三道LeetCode练习题,如455题分饼干、376题摆动子序列、53题最大子数组和,并分别阐述了解题思路。

154

被折叠的 条评论
为什么被折叠?



