贪心算法

贪心算法解决问题的步骤

第一步,当我们看到这类问题的时候,首先要联想到贪心算法:针对一组数据,我们定义了限制值和期望值,希望从中选出几个数据,在满足限制值的情况下,期满值最大。
第二步,我们尝试看下这个问题是否可以用贪心算法解决:每次选择当前情况下,在对限制值等同贡献值的情况下,对期望值贡献最大的数据。
第三步,我们举个例子看下贪心算法产生的结果是否最优的。

贪心算法实战分析

  1. 分糖果
    我们有m个糖果盒n个孩子。我们现在要把糖果分给这些孩子吃,但是糖果少,孩子多(m 解答:我们每次从剩下的孩子中,找出对糖果大小需求最小的,然后发给他剩下的糖果中能满足他的最小的糖果。

  2. 钱币找零
    假设我们有1元、2元、5元、10元、20元、50元、100元这些面额的纸币,它们的张数分别是c1、c2、c5、c10、c20、c50、c100。我们现在要用这些钱来支付K元,最少要用多少张纸币?
    解答:在贡献相同期望值(纸币数目)的情况下,我们希望多贡献点金额,这样就可以让纸币数更少。

  3. 区间覆盖
    假设我们有n个区别,区间的起始端点和结束端点分别是[l1,r1],[l2,r2],[l3,r3],.....,[ln,rn]。我们从这n个区间中选出一部分区间,这部分区间满足两两不相交(端点相交的情况不算相交),最多能选出多少个区间呢?
    解答:我们假设这n个区区间中最左端点是lmin,最右端点是rmax。这个问题就相当于,我们选择几个不相交的区间,从左到右将[lmin,rmax]覆盖上。我们按照起始端点从小到大的顺序对这n个区间排序。
    我们每次选择的时候,左端点跟前面的已经覆盖的区间不重合的,右端点又尽量小,这样可以让剩下的未覆盖区间尽可能的大,就可以放置更多的区间。

  4. 如何用贪心算法实现Huffman压缩编码?
    试图用这种不等长的编码方法,来进一步增加压缩的效率。
    转化为:如何给不同频率的字符选择不同长度的编码呢?
    解答:我们可以把出现频率比较多的字符,用稍微短一些的编码;出现频率比较少的字符,用稍微长一些的编码。
    通过优先级队列实现(存放频率)

  5. 在一个非负整数a中,我们希望从中移除k个数字,让剩下的数字值最小,如何选择移除哪k个数字呢?
    解答:由最高位开始,比较低一位数字,如高位大,移除,若高位小,则向右移一位继续比较两个数字,直到高位大于低位则移除,循环k次。

  6. 假设有n个人等待被服务,但是服务窗口只有一个,每个人需要被服务的时间长度是不同的,如何安排被服务的先后顺序,才能让这n个人总的等待时间最短?
    解答:由等待时间最短的开始服务

经典应用

  • 霍夫曼编码(Huffman Coding)
  • Prim和Kruskal最小生成树算法
  • Dijkstra单源最短路径算法。

37 | 贪心算法:如何用贪心算法实现Huffman压缩编码?

你可能感兴趣的:(贪心算法)