Java贪心算法之广播台集合覆盖问题、思路分析、代码实现

本文通过解决广播台覆盖问题,详细介绍了贪心算法的实现过程。通过选取覆盖最多未覆盖区域的广播台,逐步构建解决方案,最终达到用最少的广播台覆盖所有区域的目标。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


贪心算法

贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。


案例:广播台集合覆盖问题

如何选择最少的广播台,让所有地区都可以收到信号?

在这里插入图片描述


. 思路分析

  • 用一个arealist集合存储地区:“北京”、“上海”、“天津”、“广州”、“深圳”、“成都”、“杭州”、“大连”

  • 用一个hashmap存储广播台和覆盖范围的关系:HashMap<String, HashSet<String>>

  • 用一个keylist集合存储符合要求的电台

  • 遍历hashmap,每个key值对应的value与list集合做交集,交集的结果用key变量将电台记录下来,每次遍历都会有一个交集结果,每次就将本次的交集结果与key中的交集结果进行比较,大的就重新赋值key值,遍历完之后,就会得到本轮完整遍历的与arealist集合交集最多的那个电台,然后将该电台加入到keylist集合中,再将arealist中移除与该电台覆盖地区相同的地区。然后进入下一轮遍历hashmap,继续如上操作。

    直到arealist中无任何数据,结束。

  • 此时,keylist中存放的就是最终结果了。

贪心算法的核心就是,每次遍历都会获取到最优或最有利的值。


. 代码实现

public class Greedy {
    public static void main(String[] args) {
        // 存储需要覆盖的所有城市
        ArrayList<String> areaList = new ArrayList<>();
        areaList.add("北京");
        areaList.add("上海");
        areaList.add("天津");
        areaList.add("广州");
        areaList.add("深圳");
        areaList.add("成都");
        areaList.add("杭州");
        areaList.add("大连");

        // 存储每个电台覆盖的城市
        HashSet<String> broadcastArea1 = new HashSet<>();
        broadcastArea1.add("北京");
        broadcastArea1.add("上海");
        broadcastArea1.add("天津");
        HashSet<String> broadcastArea2 = new HashSet<>();
        broadcastArea2.add("广州");
        broadcastArea2.add("北京");
        broadcastArea2.add("深圳");
        HashSet<String> broadcastArea3 = new HashSet<>();
        broadcastArea3.add("成都");
        broadcastArea3.add("上海");
        broadcastArea3.add("杭州");
        HashSet<String> broadcastArea4 = new HashSet<>();
        broadcastArea4.add("上海");
        broadcastArea4.add("天津");
        HashSet<String> broadcastArea5 = new HashSet<>();
        broadcastArea5.add("杭州");
        broadcastArea5.add("大连");

        // 将电台与其所覆盖的城市关联起来,成为键值对
        HashMap<String, HashSet<String>> broadcasts = new HashMap<>();
        broadcasts.put("K1",broadcastArea1);
        broadcasts.put("K2",broadcastArea2);
        broadcasts.put("K3",broadcastArea3);
        broadcasts.put("K4",broadcastArea4);
        broadcasts.put("K5",broadcastArea5);

        // keyList用于存储符合要求的电台
        ArrayList<String> keyList = new ArrayList<>();
        // key用于存储每一轮遍历与areaList交集最多的电台
        String key = null;
        // 用于临时存储电台覆盖的城市
        HashSet<String> temp = new HashSet<>();

        // 结束条件是areaList没有任何数据,即说明每个城市都被覆盖了
        while (!areaList.isEmpty()){
            // 遍历broadcasts
            for (String broadcastKey : broadcasts.keySet()) {
                temp.clear(); // 一定要清空,temp是临时存储的变量
                // 将当前电台覆盖的城市添加到临时存储的变量中
                temp.addAll(broadcasts.get(broadcastKey));
                // temp集合与areaList集合取交集,交集结果赋值给temp
                temp.retainAll(areaList);
                // 判断temp的大小是否大于0,以及key值是否为空,
                // 如果不为空就判断本轮的交集大小是否大于上一次存储的key值对应的电台覆盖的城市,大于就重新赋值新的最优的结果(贪心算法核心部分)
                if (temp.size() > 0 && (key==null || temp.size() > broadcasts.get(key).size())){
                    key = broadcastKey;
                }
            }
            // 一轮遍历完之后,判断key是否为空,不为空,就将key存入到keyList集合中,表示符合要求的电台
            // 最后将符合要求的电台所覆盖的城市,从areaList集合中移除掉,说明这些城市已被覆盖
            if (key!=null){
                keyList.add(key);
                areaList.removeAll(broadcasts.get(key));
                key = null;
            }
        }

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

}

结果:

[K1, K2, K3, K5]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值