1. package com.atguigu.greedy;
    2. import org.junit.Test;
    3. import java.util.ArrayList;
    4. import java.util.HashMap;
    5. import java.util.HashSet;
    6. /**
    7. * 贪心算法 -- 集合覆盖问题
    8. *
    9. * @author Dxkstart
    10. * @create 2022-04-13-16:05
    11. */
    12. public class GreedyDemo {
    13. public static void main(String[] args) {
    14. // 创建广播电台,放入到Map
    15. HashMap<String, HashSet<String>> broadCasts = new HashMap<>();
    16. // 向broadCasts中存入电台数据
    17. HashSet<String> set1 = new HashSet<>();
    18. set1.add("北京");
    19. set1.add("上海");
    20. set1.add("天津");
    21. HashSet<String> set2 = new HashSet<>();
    22. set2.add("广州");
    23. set2.add("北京");
    24. set2.add("深圳");
    25. HashSet<String> set3 = new HashSet<>();
    26. set3.add("成都");
    27. set3.add("上海");
    28. set3.add("杭州");
    29. HashSet<String> set4 = new HashSet<>();
    30. set4.add("上海");
    31. set4.add("天津");
    32. HashSet<String> set5 = new HashSet<>();
    33. set5.add("杭州");
    34. set5.add("大连");
    35. broadCasts.put("k1",set1);
    36. broadCasts.put("k2",set2);
    37. broadCasts.put("k3",set3);
    38. broadCasts.put("k4",set4);
    39. broadCasts.put("k5",set5);
    40. // 存放所有的地区
    41. HashSet<String> allAreas = new HashSet<>();
    42. allAreas.add("北京");
    43. allAreas.add("上海");
    44. allAreas.add("天津");
    45. allAreas.add("广州");
    46. allAreas.add("深圳");
    47. allAreas.add("成都");
    48. allAreas.add("杭州");
    49. allAreas.add("大连");
    50. // 存放选择的电台
    51. ArrayList<String> selects = new ArrayList<>();
    52. // 定义一个临时的集合,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
    53. HashSet<String> tempSet = new HashSet<>();
    54. // 定义maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
    55. // 如果maxKey不为null,则会加入到selects中
    56. // allAreas.size()等于0时,说明此时电台已经覆盖完全了
    57. String maxKey = null;
    58. while (allAreas.size() != 0) {
    59. // 遍历broadCasts,取出对应的key
    60. for (String key : broadCasts.keySet()) {
    61. // 当前这个key能够覆盖的地区
    62. HashSet<String> areas = broadCasts.get(key);
    63. tempSet.addAll(areas);
    64. // 求出tempSet与allAreas的交集,交集会赋给tempSet
    65. tempSet.retainAll(allAreas);
    66. // 如果当前这个集合包含的未覆盖地区的数据,比maxKey指向的集合地区还多
    67. // 就需要重置maxKey
    68. // tempSet.size() > broadCasts.get(maxKey).size() 体现了贪心算法中的贪心 -> 每次都选择最好的
    69. if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > broadCasts.get(maxKey).size())) {
    70. maxKey = key;
    71. }
    72. // 清空交集
    73. tempSet.clear();
    74. }
    75. // 一轮循环结束
    76. if (maxKey != null) {
    77. selects.add(maxKey);
    78. // 将此次加入的电台覆盖的城市从allAreas中删除
    79. allAreas.removeAll(broadCasts.get(maxKey));
    80. maxKey = null;
    81. }
    82. }
    83. // 输出结果
    84. System.out.println("得到的结果:" + selects); // [k1, k2, k3, k5]
    85. }
    86. }

    image.png