认识贪心

  1. 贪婪算法(贪心算法)是指在对问题进行求解时,在每一步选择中都采取最好或者最优(即最有利)的选择,从而希望能够导致结果是最好或者最优的算法
  2. 贪婪算法所得到的结果不一定是最优的结果(有时候会是最优解),但是都是相对近似(接近)最优解的结果

    借集合覆盖深刻理解贪心

    image.png

我们的思路如下

  1. 遍历所有的广播电台, 找到一个覆盖了最多未覆盖的地区的电台(此电台可能包含一些已覆盖的地区,但没有关系)
  2. 将这个电台加入到一个集合中(比如ArrayList), 想办法把该电台覆盖的地区在下次比较时去掉
  3. 重复第1步直到覆盖了全部的地区

首先allAreas描述出总的城市

  • 既然要覆盖所有地区,借这个数组作为基础数据,然后逐步删除,直到为0

image.png
记录单个广播台可覆盖城市数量,同时maxKey指向最大值,从上之下

  • 当前,显然是K1

image.png
执行结束后,maxkey置空,然后把allAreas里面和K1交集的部分去掉

  • 注意allAreas的数据变化,后面不赘述

image.png
开始重新更新广播台对于的城市有效数量
image.png
刷新完毕后,key再次回到最底端,maxKey取消悬空,再次重复开头的操作

  • 我相信你已经看到其中的循环了

image.png
然后再置空,进行allAreas的更新
image.png
再次把key指向开头,然后进行广播台有效城市的更新
image.png
如此反复操作而已,直至如下
image.png
思路清晰,代码上场

  1. package com.atguigu.greedy;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.HashSet;
  5. public class GreedyAlgorithm {
  6. public static void main(String[] args) {
  7. //创建广播电台,放入到Map
  8. HashMap<String,HashSet<String>> broadcasts = new HashMap<String, HashSet<String>>();
  9. //将各个电台放入到broadcasts
  10. HashSet<String> hashSet1 = new HashSet<String>();
  11. hashSet1.add("北京");
  12. hashSet1.add("上海");
  13. hashSet1.add("天津");
  14. HashSet<String> hashSet2 = new HashSet<String>();
  15. hashSet2.add("广州");
  16. hashSet2.add("北京");
  17. hashSet2.add("深圳");
  18. HashSet<String> hashSet3 = new HashSet<String>();
  19. hashSet3.add("成都");
  20. hashSet3.add("上海");
  21. hashSet3.add("杭州");
  22. HashSet<String> hashSet4 = new HashSet<String>();
  23. hashSet4.add("上海");
  24. hashSet4.add("天津");
  25. HashSet<String> hashSet5 = new HashSet<String>();
  26. hashSet5.add("杭州");
  27. hashSet5.add("大连");
  28. //加入到map
  29. broadcasts.put("K1", hashSet1);
  30. broadcasts.put("K2", hashSet2);
  31. broadcasts.put("K3", hashSet3);
  32. broadcasts.put("K4", hashSet4);
  33. broadcasts.put("K5", hashSet5);
  34. //allAreas 存放所有的地区
  35. HashSet<String> allAreas = new HashSet<String>();
  36. allAreas.add("北京");
  37. allAreas.add("上海");
  38. allAreas.add("天津");
  39. allAreas.add("广州");
  40. allAreas.add("深圳");
  41. allAreas.add("成都");
  42. allAreas.add("杭州");
  43. allAreas.add("大连");
  44. //创建ArrayList, 存放选择的电台集合
  45. ArrayList<String> selects = new ArrayList<String>();
  46. //定义一个临时的集合, 在遍历的过程中,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
  47. HashSet<String> tempSet = new HashSet<String>();
  48. //定义给maxKey , 保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
  49. //如果maxKey 不为null , 则会加入到 selects
  50. String maxKey = null;
  51. while(allAreas.size() != 0) { // 如果allAreas 不为0, 则表示还没有覆盖到所有的地区
  52. //每进行一次while,需要
  53. maxKey = null;
  54. //遍历 broadcasts, 取出对应key
  55. for(String key : broadcasts.keySet()) {
  56. //每进行一次for
  57. tempSet.clear();
  58. //当前这个key能够覆盖的地区
  59. HashSet<String> areas = broadcasts.get(key);
  60. tempSet.addAll(areas);
  61. //求出tempSet 和 allAreas 集合的交集, 交集会赋给 tempSet
  62. tempSet.retainAll(allAreas);
  63. //如果当前这个集合包含的未覆盖地区的数量,比maxKey指向的集合地区还多
  64. //就需要重置maxKey
  65. // tempSet.size() >broadcasts.get(maxKey).size()) 体现出贪心算法的特点,每次都选择最优的
  66. if(tempSet.size() > 0 &&
  67. (maxKey == null || tempSet.size() >broadcasts.get(maxKey).size())){
  68. maxKey = key;
  69. }
  70. }
  71. //maxKey != null, 就应该将maxKey 加入selects
  72. if(maxKey != null) {
  73. selects.add(maxKey);
  74. //将maxKey指向的广播电台覆盖的地区,从 allAreas 去掉
  75. allAreas.removeAll(broadcasts.get(maxKey));
  76. }
  77. }
  78. System.out.println("得到的选择结果是" + selects);//[K1,K2,K3,K5]
  79. }
  80. }

image.png
举例
image.png


image.png
举例
image.png


package com.xy.greedy;

import java.util.HashMap;
import java.util.HashSet;

public class GreedyAlgorithm {

    public static void main(String[] args) {
        //创建广播电台,放入到Map
        HashMap<String, HashSet<String>> broadcasts = new HashMap<String, HashSet<String>>();

        HashSet<String> hashSet1 = new HashSet<>();
        hashSet1.add("北京");
        hashSet1.add("上海");
        hashSet1.add("天津");

        HashSet<String> hashSet2 = new HashSet<>();
        hashSet2.add("广州");
        hashSet2.add("北京");
        hashSet2.add("深圳");

        HashSet<String> hashSet3 = new HashSet<>();
        hashSet3.add("成都");
        hashSet3.add("上海");
        hashSet3.add("杭州");

        HashSet<String> hashSet4 = new HashSet<>();
        hashSet4.add("上海");
        hashSet4.add("天津");

        HashSet<String> hashSet5 = new HashSet<>();
        hashSet5.add("杭州");
        hashSet5.add("大连");


        //加入到Map

        broadcasts.put("K1", hashSet1);
        broadcasts.put("K2", hashSet2);
        broadcasts.put("K3", hashSet3);
        broadcasts.put("K4", hashSet4);
        broadcasts.put("K5", hashSet5);

    }

}

image.png


image.png