贪心算法的艺术:从加油站到糖果分配的实战解析

时间:2024-12-30 21:27 分类:其他教程

在算法的世界里,贪心算法以其简洁而高效的解决方案著称。今天,我们将深入探讨几道经典的算法题目,通过这些实例来揭示贪心算法的精妙之处。无论你是算法初学者还是经验丰富的程序员,这篇文章都将为你提供新的视角和解决问题的思路。

1. 加油站问题:寻找最佳起点

题目描述: 假设你有一辆环形公路上的汽车,沿途有若干加油站,每个加油站提供的油量和到达下一个加油站所需的油量各不相同。你的任务是找到一个起点,使得从这个起点出发,你能环绕整个公路。

解题思路:

  • 首先,我们计算每个加油站的净油量(油量减去消耗量)。
  • 然后,我们通过遍历这些净油量,找到一个点,使得从这个点开始的总油量始终为正。
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        total = 0
        min_val = 0
        start = 0
        for i in range(len(gas)):
            total += (gas[i] - cost[i])
            if total < min_val:
                min_val = total
                start = i + 1
        return -1 if total < 0 else start

2. 分发糖果:公平与效率的平衡

题目描述: 你需要给一群小朋友分发糖果,每个小朋友有一个评分,你希望根据他们的评分来分配糖果,规则是:评分高的孩子必须得到更多的糖果。

解题思路:

  • 我们可以从左到右遍历一次,确保右边的孩子如果评分高于左边的孩子,则得到更多的糖果。
  • 然后从右到左遍历,确保左边的孩子如果评分高于右边的孩子,也得到更多的糖果。
class Solution:
    def candy(self, ratings: List[int]) -> int:
        if not ratings: return 0
        n = len(ratings)
        left = [1] * n
        right = 1
        result = 0
        for i in range(1, n):
            if ratings[i] > ratings[i-1]:
                left[i] = left[i-1] + 1
        for i in range(n-1, -1, -1):
            if i < n-1 and ratings[i] > ratings[i+1]:
                right += 1
            else:
                right = 1
            result += max(left[i], right)
        return result

3. 柠檬水找零:巧妙的货币交换

题目描述: 你经营一个柠檬水摊,顾客会给你5美元、10美元或20美元的钞票,你需要找零。

解题思路:

  • 对于5美元的钞票,直接收下。
  • 对于10美元的钞票,找回一个5美元。
  • 对于20美元的钞票,优先找回一个10美元和一个5美元,如果没有10美元,则找回三个5美元。
class Solution:
    def lemonadeChange(self, bills: List[int]) -> bool:
        five, ten, twenty = 0, 0, 0
        for bill in bills:
            if bill == 5:
                five += 1
            elif bill == 10:
                if five > 0:
                    five -= 1
                    ten += 1
                else:
                    return False
            elif bill == 20:
                if ten > 0 and five > 0:
                    ten -= 1
                    five -= 1
                elif five >= 3:
                    five -= 3
                else:
                    return False
        return True

4. 根据身高重建队列:排序与插入的艺术

题目描述: 给定一个二维数组,其中每个元素代表一个人的身高和前面应该有多少人,重新排列这个队列。

解题思路:

  • 首先,按照身高降序、位置升序排序。
  • 然后,按照排序后的顺序插入队列。
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=lambda x: (-x[0], x[1]))
        queue = []
        for p in people:
            queue.insert(p[1], p)
        return queue

通过这些实例,我们不仅学习了如何应用贪心算法解决实际问题,更重要的是,我们理解了在不同情境下如何选择最优策略。贪心算法的魅力在于其直观性和高效性,但要真正掌握它,还需要不断地实践和思考。希望这篇文章能为你的算法学习之旅提供有价值的见解和灵感。

声明:

1、本博客不从事任何主机及服务器租赁业务,不参与任何交易,也绝非中介。博客内容仅记录博主个人感兴趣的服务器测评结果及一些服务器相关的优惠活动,信息均摘自网络或来自服务商主动提供;所以对本博客提及的内容不作直接、间接、法定、约定的保证,博客内容也不具备任何参考价值及引导作用,访问者需自行甄别。

2、访问本博客请务必遵守有关互联网的相关法律、规定与规则;不能利用本博客所提及的内容从事任何违法、违规操作;否则造成的一切后果由访问者自行承担。

3、未成年人及不能独立承担法律责任的个人及群体请勿访问本博客。

4、一旦您访问本博客,即表示您已经知晓并接受了以上声明通告。

本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。

评论 0人参与,0条评论
查看更多

Copyright 2005-2024 yuanmayuan.com 源码园 版权所有 备案信息

声明: 本站非腾讯QQ官方网站 所有软件和文章来自互联网 如有异议 请与本站联系 本站为非赢利性网站 不接受任何赞助和广告