算法系列之贪心算法

e540d597-0ebc-418e-be26-015086b19459.jpg

在算法中,贪心算法(Greedy Algorithm)是一种常见的解决优化问题的算法。贪心算法的核心思想是:在每一步选择中都采取当前状态下最优的选择,即贪心的做出局部最优的决策,从而希望最终能够得到全局最优解。尽管贪心算法并不总是能够得到全局最优解,但在许多实际问题中,它能够提供足够好的解决方案,并且具有较高的计算效率。

本文将详细介绍贪心算法的基本概念、优缺点、实现步骤以及适用场景,并通过示例问题来展示贪心算法的应用。

基本概念

贪心算法它在每一步选择中都做出局部最优的选择,希望通过一系列局部最优的选择最终达到全局最优。贪心算法不会考虑过去的决策,而是一路向前的进行贪心的选择,不断缩小问题的范围,直至问题被解决。

我们通过找零问题来了解下贪心算法的工作原理:

问题描述:给定不同面额的硬币和一个总金额,要求用最少数量的硬币凑成该金额。

贪心策略:每次选择不大于且最接近剩余金额的最大的硬币,直到凑够总金额。

如图所示:我们需要找到凑够181元金额最少的硬币

_20250222204509.jpg

优点及局限性

优点:

  • 高效性:贪心算法通常具有较高的计算效率,适用于大规模问题。

  • 简单性:贪心算法的实现通常较为简单,易于理解和编码。

缺点:

  • 局部最优不一定全局最优:贪心算法并不总是能够得到全局最优解,有时只能得到近似解。

  • 适用范围有限:贪心算法仅适用于具有贪心选择性质和最优子结构的问题。

示例:

比如币种有【1,20,50】,金额为60的话贪心算法只能找到 50+1*10 的兑换组合,有11张,而动态规划可以找到 20*3共3张的最优解。

贪心算法的实现步骤

贪心算法的实现通常包括以下几个步骤:

  1. 问题建模:将问题抽象为一个优化问题,明确目标函数和约束条件。

  2. 选择策略:确定每一步的局部最优选择策略。

  3. 迭代求解:从初始状态开始,逐步应用选择策略,直到达到终止条件。

  4. 验证解的有效性:验证最终得到的解是否满足问题的要求,并判断是否为全局最优解。

适用场景

  1. 最优化问题

问题需要找到最大值或最小值。

  • 找零问题(用最少数量的硬币找零)。
  • 最小生成树问题(Prim算法、Kruskal算法)。
  • 最短路径问题(Dijkstra算法)。
  1. 区间问题

问题涉及区间选择或区间调度。

  • 活动选择问题(选择最多的互不冲突的活动)。
  • 区间覆盖问题(用最少的区间覆盖所有点)。
  1. 分配问题

问题涉及资源的分配或任务的调度。

  • 背包问题(分数背包问题,贪心算法可解)。
  • 任务调度问题(最小化完成时间或最大化任务数量)。
  1. 组合问题

问题涉及从一组元素中选择子集,满足某些条件。

  • 霍夫曼编码(构建最优前缀编码)。
  • 集合覆盖问题(近似解法)。

Java 实现示例

我们就用代码实现我们上边所示的找零问题,金额 161,面额【1,5,10,20,50,100】。代码如下:

/**
 * 贪心算法
 * 金额 161,面额[1,5,10,20,50,100],求最少的硬币个数
 */
public class GreedyCoin {
   

    /**
     * 求解最少硬币个数
     * @param amount
     * @param coins
     * @return
     */
    public static int minCoin(int amount, int[] coins) {
   
        //排序硬币面值
        Arrays.sort(coins)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修己xj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值