贪心算法解决电台覆盖问题

贪心算法解决电台覆盖问题

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

广播台覆盖区域
K1北京, 天津, 上海
K2广州, 北京, 深圳
K3成都, 上海, 杭州
K4上海, 天津
K5杭州, 大连
所有需要覆盖的区域成都, 上海, 广州, 天津, 大连, 杭州, 北京, 深圳

思路分析

  • 当HashSet存储所有需要覆盖的区域,当需要覆盖的区域的个数大于0,进行循环
  • 每次循环,对广播台进行遍历,选取与所有需要覆盖的区域的交集个数最多的广播台作为选择对象加入选择集合
  • 交集个数最多的广播台加入选择集合后,从所有需要覆盖的区域中去除该广播台覆盖的区域,然后进入下一次循环,直到需要覆盖的区域的个数等于0

代码实现

public class GreedyAlgorithm {
    public static void main(String[] args) {
        //创建广播台放入set中
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
        //将各个广播台 放入broadcasts
        HashSet<String> radio1 = new HashSet<>();
        radio1.add("北京");
        radio1.add("上海");
        radio1.add("天津");

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

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

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

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

        broadcasts.put("K1", radio1);
        broadcasts.put("K2", radio2);
        broadcasts.put("K3", radio3);
        broadcasts.put("K4", radio4);
        broadcasts.put("K5", radio5);

        //将每个广播台的区域加入所有区域,set自动去重
        HashSet<String> areas = new HashSet<>();
        radio1.forEach(city -> areas.add(city));
        radio2.forEach(city -> areas.add(city));
        radio3.forEach(city -> areas.add(city));
        radio4.forEach(city -> areas.add(city));
        radio5.forEach(city -> areas.add(city));
        System.out.println(areas);

        //创建ArrayList 存放选择的广播台集合
        List<String> selects = new ArrayList<>();

        //定义临时集合 存放广播台覆盖的地区和全部地区的交集
        HashSet<String> tempSet = new HashSet<>();

        String maxKey = null;
        //存放maxKey所指向的广播台的区域
        HashSet<String> maxSet = new HashSet<>();

        while (areas.size() > 0) {
            for (String key : broadcasts.keySet()) {
                //当前这个广播台能覆盖的区域
                HashSet<String> area = broadcasts.get(key);
                //放入临时变量
                tempSet.addAll(area);
                //当前这个广播台和全部区域取交集后放入tempSet
                tempSet.retainAll(areas);
                //如果maxKey 不为空 则取出这个广播台和全部区域取交际后存入maxSet
                if (maxKey != null) {
                    HashSet<String> maxArea = broadcasts.get(maxKey);
                    maxSet.addAll(maxArea);
                    maxSet.retainAll(areas);
                }
                //如果当前这个广播台和全部区域的交际个数大于零
                // 且 它的个数大于之前maxKey所指向的广播台与全部区域的交集的个数
                if (tempSet.size() > 0 && (maxKey == null || tempSet.size() > maxSet.size())) {
                    //让maxKey指向当前这个广播台
                    maxKey = key;
                }
                //清空tempSet
                tempSet.clear();
            }
            //maxKey不为空 将其加入选择的集合selects
            selects.add(maxKey);
            //将maxKey所指向的广播台所覆盖的区域从全部区域中去掉
            areas.removeAll(broadcasts.get(maxKey));
            //清除已经选择的广播台
            broadcasts.remove(maxKey);
            //置空maxKey
            maxKey = null;
        }
        System.out.println("选择的结果为:"+selects);
    }
}

输出

选择的结果为:[K1, K2, K3, K5]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值