目录
贪心算法理论基础
Referece:代码随想录 (programmercarl.com)
LeetCode455.分发饼干
链接:LeetCode455. 455. 分发饼干 - 力扣(LeetCode)
1. 思路
为了满足更多的小孩,就不要造成饼干尺寸的浪费。大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子,那么就应该优先满足胃口大的。
这里的局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩。
可以尝试使用贪心策略,先将饼干数组和小孩数组排序。然后从后向前遍历小孩数组,用大饼干优先满足胃口大的,并统计满足小孩数量。
这个例子可以看出饼干9只有喂给胃口为7的小孩,这样才是整体最优解,并想不出反例,那么就可以写代码了;
2. 代码实现
实现思路1:优先分饼干,给饼干找合适的孩子
局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩;
优先把饼干喂出去,如果饼干满足不了当前的孩子,就换个胃口小的孩子,最后喂出去的饼干个数,就是满足的孩子的数量;
可以采用双指针法,初始都定义在数组的最后一位;然后根据情况向前移动;
# 优先把饼干分出去,把大饼干分给胃口大的
# 如果大饼干满足不了当前的孩子,就找个胃口更小的孩子分
# 最后饼干分出去的数量,就是满足的孩子的个数
# 双指针法+贪心
# time:**max( O(MlogM), O(NlogN) )**;space:O(1)
class Solution(object):
def findContentChildren(self, g, s):
"""
:type g: List[int]
:type s: List[int]
:rtype: int
"""
g.sort()
s.sort()
child = len(g)-1
cookie = len(s)-1
count = 0
while child>=0 and cookie>=0:
# 如果当前饼干满足当前孩子
if s[cookie]>=g[child]:
count += 1
cookie -= 1
child -= 1
# 如果当前饼干不满足当前孩子,找胃口更小的孩子
else:
child -= 1
return count
也可以这样写,既然是优先分饼干,那就遍历孩子:
有的同学看到要遍历两个数组,就想到用两个for循环,那样逻辑其实就复杂了,可以用一个index来控制饼干数组的遍历,遍历饼干并没有再起一个for循环,而是采用自减的方式,这也是常用的技巧。
class Solution:
def findContentChildren(self, g: List[int], s: List[int]) -> int:
g.sort()
s.sort()
start, count = len(s) - 1, 0
for index in range(len(g) - 1, -1, -1):
if start >= 0 and g[index] <= s[start]:
start -= 1
count += 1
return count
实现思路2:优先喂饱孩子,给孩子找合适的饼干
局部最优就是小饼干喂给胃口小的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩;
优先把孩子满足,给胃口小的分小饼干,如果当前饼干满足不了当前孩子,就找个更大的饼干给他,最后孩子遍历到的位置,就是可以满足的孩子的数量;
可以采用双指针法,初始都定义在数组的第一位;然后根据情况向后移动;
# 优先把孩子满足,把小饼干分给胃口小的
# 如果当前饼干满足不了当前的孩子,就找个更大的饼干给他
# 最后孩子遍历到的位置,就是可以满足的孩子的数量
# 双指针法+贪心
# time:**max( O(MlogM), O(NlogN) )**;space:O(1)