目录
贪心算法
贪心算法的定义
贪心算法,也被称为贪婪算法,是一种寻找最优解问题的常用策略。这种算法的基本模式是将求解过程分成若干个步骤,在每个步骤中都应用贪心原则,选择当前状态下最好或最优的选择(局部最有利的选择),并期望通过这种方式能够产生全局最优解。
贪心算法的中心思想
贪心算法的基本思想是在问题的求解过程中,每一步都选择当前状态下最优(或最有利)的选择,寄希望于这样的局部最优解能推导出全局最优解。这种算法的实现步骤通常包括:首先建立问题的数学模型;然后将大问题分解为若干个子问题;接着对每一个子问题求解,得到子问题的局部最优解;最后将子问题的局部最优解合成原来问题的一个解。
贪心算法的不足
值得注意的是,贪心算法并不总是能够找到全局最优解,而是在许多情况下,它寻求的是某种意义上的局部最优解。此外,贪心算法的核心在于贪心策略的选择,该策略需要满足无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
贪心算法的练习题
柠檬水找零问题
(1)问题描述
在柠檬水摊上,每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品,(按账单 bills 支付的顺序)一次购买一杯。
每位顾客只买一杯柠檬水,然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零,也就是说净交易是每位顾客向你支付 5 美元。
注意,一开始你手头没有任何零钱。
给你一个整数数组 bills ,其中 bills[i] 是第 i 位顾客付的账。如果你能给每位顾客正确找零,返回 true ,否则返回 false 。
(2)输入输出示例
示例 1:
输入:bills = [5,5,5,10,20]输出:true解释:前 3 位顾客那里,我们按顺序收取 3 张 5 美元的钞票。
第 4 位顾客那里,我们收取一张 10 美元的钞票,并返还 5 美元。
第 5 位顾客那里,我们找还一张 10 美元的钞票和一张 5 美元的钞票。
由于所有客户都得到了正确的找零,所以我们输出 true。
示例 2:
输入:bills = [5,5,10,10,20]输出:false解释:
前 2 位顾客那里,我们按顺序收取 2 张 5 美元的钞票。
对于接下来的 2 位顾客,我们收取一张 10 美元的钞票,然后返还 5 美元。
对于最后一位顾客,我们无法退回 15 美元,因为我们现在只有两张 10 美元的钞票。
由于不是每位顾客都得到了正确的找零,所以答案是 false。
(3)解题思路
A.初始化两个变量 five 和 ten,分别表示5美元和10美元的数量。
B.遍历顾客支付的账单列表 bills。
C.如果顾客支付的是5美元,将 five 的值加1。
D.如果顾客支付的是10美元,首先检查是否有5美元的零钱,如果没有则返回False,否则将 five 的值减1,将 ten 的值加1。
E.如果顾客支付的是20美元,优先使用10美元和5美元的组合找零,如果没有10美元和5美元的组合,再尝试使用3个5美元找零。如果都无法找零,则返回False。
F.如果所有顾客都能顺利找零,最后返回True。
(4)代码实现
class Solution(object):
def lemonadeChange(self, bills):
five = ten = 0
for bill in bills:
if bill == 5:
five += 1
elif bill == 10:
if not five: return False
five -= 1
ten += 1
else:
if ten and five:
ten -= 1
five -= 1
elif five >= 3:
five -= 3
else:
return False
return True
"""
:type bills: List[int]
:rtype: bool
"""
分发饼干问题
(1)问题描述
假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。
对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] >= g[i],我们可以将这个饼干 j 分配给孩子 i ,这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子,并输出这个最大数值。
(2)输入输出示例
示例 1:
输入: g = [1,2,3], s = [1,1]输出: 1解释:
你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。
虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子 满足。
所以你应该输出1。
示例 2:
输入: g = [1,2], s = [1,2,3]输出: 2解释:
你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。
你拥有的饼干数量和尺寸都足以让所有孩子满足。
所以你应该输出2.
(3)解题思路
首先对孩子的胃口值进行排序,然后遍历饼干尺寸,将满足条件的饼干分配给孩子。具体步骤如下:
A.对胃口值数组 g 进行升序排序。
B.初始化一个计数器 count 用于记录满足条件的孩子数量。
C.遍历饼干尺寸数组 s,对于每个饼干尺寸,检查是否有孩子可以满足这个饼干。如果有,将这个饼干分配给满足条件的孩子,并将孩子的胃口值从数组中移除。同时,将计数器 count 加1。
D.当所有的饼干都被分配完或者没有孩子可以满足时,结束循环。
E.返回计数器 count 的值,即满足条件的孩子数量。
(4)代码实现
class Solution(object):
def findContentChildren(self, g, s):
g.sort()
s.sort()
child_i = cookie_j = 0
while child_i < len(g) and cookie_j < len(s):
if s[cookie_j] >= g[child_i]:
child_i += 1
cookie_j += 1
return child_i
"""
:type g: List[int]
:type s: List[int]
:rtype: int
"""
1252

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



