贪心算法解决集合覆盖问题

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

public class Greedy {
     
    public static void main(String[] args) {
     
        //集合覆盖问题
        //首先,需要一个Map存储电台对应的覆盖区域
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();

        //还需要一个存储所有城市的集合
        HashSet<String> allAreas = new HashSet<>();

        //需要一个存储所选电台的集合
        ArrayList<String> selects = new ArrayList<>();

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

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

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

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

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

        broadcasts.put("k1",hs1);
        broadcasts.put("k2",hs2);
        broadcasts.put("k3",hs3);
        broadcasts.put("k4",hs4);
        broadcasts.put("k5",hs5);

        //遍历broadcasts, 得到所有区域
        for(String key : broadcasts.keySet()){
     
            allAreas.addAll(broadcasts.get(key));
        }

        //测试获取所有区域是否正确
        //System.out.println(allAreas);

        //开始处理
        String maxKey;
        //存储每个电台覆盖的区域 与 allAreas 的交集,即用来得到每一次覆盖区域的最大的电台
        HashSet<String> tempSet = new HashSet<>();

        while (allAreas.size() > 0){
     
            maxKey = null;//注意,每一次while循环,maxKey都要置空
            
            for(String key : broadcasts.keySet()){
     
                
                tempSet.clear();//注意!!每一次循环都要清空上一次循环的tempSet的内容
                
                tempSet.addAll(broadcasts.get(key));
                tempSet.retainAll(allAreas);//获取tempSet 与 allAreas 的交集

                HashSet<String> pre = new HashSet<>();//如果maxKey不为空,则需要和前一次的比较大小,所以也要取交集
                if (maxKey != null){
     
                    pre.addAll(broadcasts.get(maxKey));
                    pre.retainAll(allAreas);
                }

                if(tempSet.size() > 0 && (maxKey == null || tempSet.size() > pre.size())){
     
                    maxKey = key;
                }
            }
            //退出for循环后,已经取得本轮的最大覆盖区域的电台
            if(maxKey != null){
     
                selects.add(maxKey);
                //将maxKey对于的电台覆盖的区域从allAreas中抹去
                allAreas.removeAll(broadcasts.get(maxKey));//这就是 pre 也要取交集的原因
            }
        }

        //输出结果
        System.out.println(selects);
    }
}

你可能感兴趣的:(hashmap,java)