提出问题:
使用贪心算法解决该问题:
主要思路:
- 遍历所有广播电台,找到一个覆盖了最多未覆盖地区的电台;
- 将这个电台加入一个集合中(如ArrayList),并将该电台已覆盖的地区从未覆盖地区集中删掉;
- 重复1、2步,直至无未覆盖地区。
代码实现:
package DataStructure;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class GreedyDemo {
public static void main(String[] args) {
// 创建广播电台放入map,key储存电台名,value储存地区集
HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
HashSet<String> area1 = new HashSet<>();
area1.add("北京");
area1.add("上海");
area1.add("天津");
broadcasts.put("k1", area1);
HashSet<String> area2 = new HashSet<>();
area2.add("北京");
area2.add("广州");
area2.add("深圳");
broadcasts.put("k2", area2);
HashSet<String> area3 = new HashSet<>();
area3.add("成都");
area3.add("上海");
area3.add("杭州");
broadcasts.put("k3", area3);
HashSet<String> area4 = new HashSet<>();
area4.add("上海");
area4.add("天津");
broadcasts.put("k4", area4);
HashSet<String> area5 = new HashSet<>();
area5.add("杭州");
area5.add("大连");
broadcasts.put("k5", area5);
// allAreas 存放所有地区
HashSet<String> allAreas = new HashSet<>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");
// selects 存放选中的电台
List<String> selects = new ArrayList<>();
HashSet<String> tempArea;
String maxKey = null; // 储存包含剩下地区最多的电台的key值
// 循环直到allAreas为空,即所有地区都已被覆盖
while (allAreas.size() != 0) {
// 定义变量count记录电台能覆盖的地区与剩下地区的交集数量的最大值
int count = 0;
// 遍历所有电台
for (String key : broadcasts.keySet()) {
tempArea = broadcasts.get(key);
// 求出电台能覆盖的地区与剩下地区的交集
tempArea.retainAll(allAreas);
// 如果后续电台的交集数量大于之前电台的交集数量,则更新maxKey和count值
if (tempArea.size() > count) {
maxKey = key;
count = tempArea.size();
}
}
if (maxKey != null) {
// 完成一轮遍历,选出了覆盖剩下地区最多的电台
selects.add(maxKey);
// 从地区集中移除已覆盖的地区
allAreas.removeAll(broadcasts.get(maxKey));
}
}
System.out.println(selects); // [k1, k2, k3, k5]
}
}