贪心算法

116 阅读2分钟

贪心算法(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);
    }

}