贪心算法(greedy algorithm)

什么是贪心算法

贪心算法是常见的优化问题的方法,它在问题的每个阶段都寻求最优解,既贪心的做出局部最优解

零钱兑换问题

一个简单的贪心算法问题

题干:你有一个硬币数组coins[](数组中默认增序),里面存储了若干面值的硬币,写一个函数coinChangeGreedy(int[] coins,int atm),判断是否能用硬币数组里的面额付清atm(目标金额),若能返回找钱次数count,若不能则返回-1。

思考:我们要解决这个问题的步骤首先是找到数组coins[]中小于等于atm的最大金额coins[i],然后目标金额atm-coins[i],count++。

通过思考我们需要一个循环套一个循环,大循环执行atm-coins[i],count++,内部循环寻找符合满足coins[i] <= atm的第一个元素。

代码如下

int coinChangeGreedy(int[] coins, int atm) {
        int i = coins.length - 1;
        int count = 0;//标识找钱次数
        while (atm > 0) {
            //每次都找到小于等于atm的钱
            while (i > 0 && coins[i] > atm) {
                    i--;
            }
            //找到最适合的coins[i]
            atm -= coins[i];
            count++;
        }
        //返回找钱次数,若找不开则返回-1
        return atm == 0 ? count : -1;
    }

 贪心算法的优点和局限

贪心算法操作直接,实现简单,通常效率也高,但可能不会找到最优解。

在coins[1,5,10,20,,50,100]来找任意金额都能找到最优解

但coins[1,20,50]来找60只能找到一个50,十个1,一共11个硬币,但动态规划直接能找到3个20

在coins[1,49,50]来找98,用贪心算法要找一张50和四十八张1共49个,但动态规划只需要2个

贪心算法的性质

整个问题的最优解是每个局部问题的最优解

贪心算法典型用例

硬币找零问题:在某些硬币组合下,贪心算法总是可以得到最优解。

区间调度问题:假设你有一些任务,每个任务在一段时间内进行,你的目标是完成尽可能多的任务。如果每次都选择结束时间最早的任务,那么贪心算法就可以得到最优解。

分数背包问题:给定一组物品和一个载重量,你的目标是选择一组物品,使得总重量不超过载重量,且总价值最大。如果每次都选择性价比最高(价值 / 重量)的物品,那么贪心算法在一些情况下可以得到最优解。

股票买卖问题:给定一组股票的历史价格,你可以进行多次买卖,但如果你已经持有股票,那么在卖出之前不能再买,目标是获取最大利润。

霍夫曼编码:霍夫曼编码是一种用于无损数据压缩的贪心算法。通过构建霍夫曼树,每次选择出现频率最低的两个节点合并,最后得到的霍夫曼树的带权路径长度(编码长度)最小。

Dijkstra 算法:它是一种解决给定源顶点到其余各顶点的最短路径问题的贪心算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值