贪心算法 - LeetCode 每日刷题精华 (Day 7)
2024-01-31 07:24:39
贪心算法:优化决策,解决复杂问题
引言
在计算机科学领域,贪心算法是一种常用的方法,它通过在每一步中做出局部最优决策来解决问题,从而得到全局最优解或近似最优解。贪心算法简单易懂,实现高效,在解决许多实际问题中都有着广泛的应用。
贪心算法的原理
贪心算法的基本思想是在每次决策中选择当前看来最优的选项,而不考虑未来可能出现的更优选项。这种方法虽然不能保证得到全局最优解,但通常可以得到近似最优解,并且在时间和空间复杂度上具有优势。
LeetCode每日一题:贪心算法的实战应用
1. 分配饼干
问题:给定一数组 children 和一数组 cookies,表示 n 个孩子和 n 个饼干,每个孩子有一个胃口值,每个饼干有一个大小值。一个孩子只能吃一个饼干,饼干的大小值必须大于或等于孩子的胃口值。求最多能满足多少孩子。
贪心算法解法:
- 将孩子和饼干按胃口值和大小值从小到大排序。
- 从头开始遍历孩子和饼干数组,如果某个孩子的胃口值小于或等于某个饼干的大小值,则该孩子可以吃该饼干。
def findContentChildren(children, cookies):
children.sort()
cookies.sort()
i, j = 0, 0
cnt = 0
while i < len(children) and j < len(cookies):
if children[i] <= cookies[j]:
cnt += 1
i += 1
j += 1
else:
j += 1
return cnt
2. 不重叠区间个数
问题:给定一个区间数组 intervals,其中每个区间都有一个起始和结束时间,求不重叠区间的最大数量。
贪心算法解法:
- 按区间的结束时间从小到大排序。
- 从头开始遍历区间数组,如果当前区间的起始时间大于或等于上一个区间的结束时间,则该区间可以加入不重叠区间集合中。
def eraseOverlapIntervals(intervals):
intervals.sort(key=lambda x: x[1])
cnt = 0
prev = -1e9
for interval in intervals:
if interval[0] >= prev:
cnt += 1
prev = interval[1]
return cnt
3. 投飞镖刺破气球
问题:给定一个气球数组 balloons,其中每个气球有一个刺破气球需要的分数。求刺破所有气球的最小分数。
贪心算法解法:
- 按气球分数从小到大排序。
- 从头开始遍历气球数组,如果当前气球分数小于或等于上一个气球分数,则当前气球分数可以累加到总分数中。
def minNumberOfArrowsToBurstBalloons(balloons):
balloons.sort(key=lambda x: x[1])
cnt = 1
prev = balloons[0][1]
for balloon in balloons:
if balloon[0] >= prev:
cnt += 1
prev = balloon[1]
return cnt
4. 根据身高和序号重组队列
问题给定一个数组 people,其中每个元素是一个人的信息,包括身高和序号。求将人们按照身高从高到矮重组队列,并保证序号顺序不变。
贪心算法解法:
- 按身高从高到矮排序。
- 按序号依次将人插入重组队列中。
def reconstructQueue(people):
people.sort(key=lambda x: (-x[0], x[1]))
res = []
for p in people:
res.insert(p[1], p)
return res
5. 买卖股票最大收益
问题:给定一个价格数组 prices,表示股票每天的价格。求买卖股票的最大收益。
贪心算法解法:
- 按日期遍历价格数组。
- 如果当前价格大于或等于上一个价格,则当前价格可以作为卖出价格。
- 如果当前价格小于上一个价格,则当前价格可以作为买入价格。
def maxProfit(prices):
buy = 0
sell = 1
profit = 0
while sell < len(prices):
if prices[sell] < prices[buy]:
buy = sell
else:
profit = max(profit, prices[sell] - prices[buy])
sell += 1
return profit
6. 买卖股票最大收益 II
问题:给定一个价格数组 prices,表示股票每天的价格。求可以进行多次买卖股票的最大收益。
贪心算法解法:
- 按日期遍历价格数组。
- 如果当前价格大于或等于上一个价格,则当前价格可以作为卖出价格。
- 如果当前价格小于上一个价格,则忽略当前价格。
def maxProfit(prices):
profit = 0
for i in range(1, len(prices)):
if prices[i] > prices[i-1]:
profit += prices[i] - prices[i-1]
return profit
总结
贪心算法是一种强大的算法范式,它简单易懂,实现高效,在解决许多实际问题中都有着广泛的应用。通过以上六个 LeetCode 每日一题,我们深入理解了贪心算法的原理和解题思路。
常见问题解答
1. 贪心算法总是能得到全局最优解吗?
答:不,贪心算法不总是能得到全局最优解,它只能得到局部最优解或近似最优解。
2. 贪心算法的优势和劣势是什么?
答:贪心算法的优势是简单易懂,实现高效,适用于解决许多实际问题。劣势是它不总是能得到全局最优解,而且对于某些问题,贪心算法可能无法得到好的解。
3. 什么时候应该使用贪心算法?
答:当问题具有以下特性时,可以使用贪心算法:1) 每个决策只影响局部;2) 总是存在一个局部最优决策;3) 局部最优决策的集合可以得到全局最优解或近似最优解。
4. 贪心算法的应用有哪些?
答:贪心算法广泛应用于解决各种问题,包括调度、分配、路径规划、数据结构维护等。
5. 贪心算法与动态规划的区别是什么?
答:贪心算法只考虑当前局部最优决策,而动态规划会考虑所有可能的情况,找到最优决策。贪心算法实现简单,但不能保证全局最优解,而动态规划虽然实现复杂,但能保证全局最优解。