package com.atguigu.greedy;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
/**
* 贪心算法 -- 集合覆盖问题
*
* @author Dxkstart
* @create 2022-04-13-16:05
*/
public class GreedyDemo {
public static void main(String[] args) {
// 创建广播电台,放入到Map
HashMap<String, HashSet<String>> broadCasts = new HashMap<>();
// 向broadCasts中存入电台数据
HashSet<String> set1 = new HashSet<>();
set1.add("北京");
set1.add("上海");
set1.add("天津");
HashSet<String> set2 = new HashSet<>();
set2.add("广州");
set2.add("北京");
set2.add("深圳");
HashSet<String> set3 = new HashSet<>();
set3.add("成都");
set3.add("上海");
set3.add("杭州");
HashSet<String> set4 = new HashSet<>();
set4.add("上海");
set4.add("天津");
HashSet<String> set5 = new HashSet<>();
set5.add("杭州");
set5.add("大连");
broadCasts.put("k1",set1);
broadCasts.put("k2",set2);
broadCasts.put("k3",set3);
broadCasts.put("k4",set4);
broadCasts.put("k5",set5);
// 存放所有的地区
HashSet<String> allAreas = new HashSet<>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");
// 存放选择的电台
ArrayList<String> selects = new ArrayList<>();
// 定义一个临时的集合,存放遍历过程中的电台覆盖的地区和当前还没有覆盖的地区的交集
HashSet<String> tempSet = new HashSet<>();
// 定义maxKey,保存在一次遍历过程中,能够覆盖最大未覆盖的地区对应的电台的key
// 如果maxKey不为null,则会加入到selects中
// allAreas.size()等于0时,说明此时电台已经覆盖完全了
String maxKey = null;
while (allAreas.size() != 0) {
// 遍历broadCasts,取出对应的key
for (String key : broadCasts.keySet()) {
// 当前这个key能够覆盖的地区
HashSet<String> areas = broadCasts.get(key);
tempSet.addAll(areas);
// 求出tempSet与allAreas的交集,交集会赋给tempSet
tempSet.retainAll(allAreas);
// 如果当前这个集合包含的未覆盖地区的数据,比maxKey指向的集合地区还多
// 就需要重置maxKey
// tempSet.size() > broadCasts.get(maxKey).size() 体现了贪心算法中的贪心 -> 每次都选择最好的
if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > broadCasts.get(maxKey).size())) {
maxKey = key;
}
// 清空交集
tempSet.clear();
}
// 一轮循环结束
if (maxKey != null) {
selects.add(maxKey);
// 将此次加入的电台覆盖的城市从allAreas中删除
allAreas.removeAll(broadCasts.get(maxKey));
maxKey = null;
}
}
// 输出结果
System.out.println("得到的结果:" + selects); // [k1, k2, k3, k5]
}
}