贪心算法(Greedy Algorithm)是一种解决优化问题的算法设计策略,其基本思想是每一步选择当前状态下的最佳解决方案,从而希望最终能够得到全局最优解。贪心算法通常用于那些具有最优子结构性质的问题,其中问题的整体最优解可以通过一系列局部最优的选择得到。 贪心算法的一般步骤如下:
1.初始状态:从问题的初始状态开始。
2.做出选择:在当前状态下,根据某种规则或权衡,选择一个局部最优的解决方案。
3.更新状态:将所选的解决方案应用到当前状态,从而得到一个新的状态。
4.终止条件:检查是否满足终止条件,如果满足,则算法结束;如果不满足,返回步骤2。
贪心算法的优点是简单而高效,通常具有较低的时间复杂度。然而,它并不总是能够找到全局最优解,因为它依赖于局部最优选择。因此,在使用贪心算法时,必须仔细分析问题的特性,以确保贪心选择的正确性。 贪心算法的经典应用包括:
1.找零问题:如何用最少数量的硬币找零。
2.活动选择问题:在一组互相冲突的活动中,选择最多的活动,使它们不相互冲突。
3.霍夫曼编码:用于数据压缩的一种编码算法。
4.最小生成树问题:在图中找到连接所有顶点的最小权重边的集合。
5.最短路径问题:找到从一个顶点到另一个顶点的最短路径。
需要注意的是,并非所有问题都适合贪心算法,因为有些问题的最优解可能不是通过贪心选择得到的。在应用贪心算法时,必须进行充分的问题分析和验证,以确保其有效性。
找零问题:
public class Leetcode_322 {
//第一个参数是硬币面额的数组,第二个参数是需要的金额
public int coinChange(int[] coins,int amount){
int remainder = amount;
int count = 0;
for (int coin : coins) { // 5 2
while(remainder > coin){
remainder -= coin;
count++;
}
//收尾用的,比如15 可以3个5元,最后一个5元后退出循环
if(remainder == coin){
remainder = 0;
count++;
break;
}
}
if(remainder > 0){
return -1;
}else {
return count;
}
}
public static void main(String[] args) {
Leetcode_322 leetcode = new Leetcode_322();
// int count = leetcode.coinChange(new int[]{5,2,1},18);
// int count = leetcode.coinChange(new int[]{5,2,1},18);
// int count = leetcode.coinChange(new int[]{25,10,5,1},41);
//问题1 没有回头,导致找到更差的解
// int count = leetcode.coinChange(new int[]{15,10,1},21);
//问题2 没有回头,导致无解
int count = leetcode.coinChange(new int[]{15,10},20);
System.out.println(count);
}
}