贪心-集合覆盖(简单例子)

例子很简单,主要是了解这种思想–贪心算法[^11]

题目

假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。 如何选择最少的广播台,让所有的地区都可以接收到信号

广播台 覆盖地区
K1 “北京”, “上海”, “天津”
K2 “广州”, “北京”, “深圳”
K3 “成都”, “上海”, “杭州”
K4 “上海”, “天津”
K5 “杭州”, “大连”

步骤

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

代码

GreedyAlgorithm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.yukinoshita.algorithm.greedy;

import java.util.ArrayList;
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>>();
//将各个电台放入到broadcasts
HashSet<String> hashSet1 = new HashSet<String>();
hashSet1.add("北京");
hashSet1.add("上海");
hashSet1.add("天津");

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

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


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

HashSet<String> hashSet5 = new HashSet<String>();
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);

//allAreas 存放所有地区
HashSet<String> allAreas = new HashSet<String>();
allAreas.add("北京");
allAreas.add("上海");
allAreas.add("天津");
allAreas.add("广州");
allAreas.add("深圳");
allAreas.add("成都");
allAreas.add("杭州");
allAreas.add("大连");

//创建ArrayList 存放所有地区
ArrayList<String> selects = new ArrayList<String>();

//遍历过程中的电台覆盖的地区和当前还没有覆盖的地区
HashSet<String> tempSet = new HashSet<String>();


String maxKey = null;
while (allAreas.size() != 0) {
maxKey = null;

for (String key : broadcasts.keySet()) {
tempSet.clear();
HashSet<String> areas = broadcasts.get(key);
tempSet.addAll(areas);
tempSet.retainAll(allAreas);//retainAll是取出tempSet和allAreas中公共的,重新赋值给tempSet
if (tempSet.size() > 0 &&
(maxKey == null || tempSet.size() > broadcasts.get(maxKey).size())) {
maxKey = key;
}
}
if (maxKey != null) {
selects.add(maxKey);
allAreas.removeAll(broadcasts.get(maxKey));
}

}

System.out.println("选择的电台为" + selects);//[K1,K2,K3,K5]


}

}