栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【程序员必会十大算法】之贪心算法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【程序员必会十大算法】之贪心算法

例题

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

代码
public class Main {
    public static void main(String[] args) {
        
        //创建一个总的 能装得下所有的广播台和电视台
        HashMap> broadcastsAndCitys = new HashMap<>();

        //分别创建每一个广播台的覆盖地区,然后加到总的集合中
        HashSet K1 = new HashSet<>();
        K1.add("北京");
        K1.add("上海");
        K1.add("天津");
        HashSet K2 = new HashSet<>();
        K2.add("广州");
        K2.add("北京");
        K2.add("深圳");
        HashSet K3 = new HashSet<>();
        K3.add("成都");
        K3.add("上海");
        K3.add("杭州");
        HashSet K4 = new HashSet<>();
        K4.add("上海");
        K4.add("天津");
        HashSet K5 = new HashSet<>();
        K5.add("杭州");
        K5.add("大连");

        //然后将每一个覆盖地区,以及广播台名,加入到总的集合中
        broadcastsAndCitys.put("k1",K1);
        broadcastsAndCitys.put("k2",K2);
        broadcastsAndCitys.put("k3",K3);
        broadcastsAndCitys.put("k4",K4);
        broadcastsAndCitys.put("k5",K5);

        System.out.println(broadcastsAndCitys);//{k1=[上海, 天津, 北京], k2=[广州, 北京, 深圳], k3=[成都, 上海, 杭州], k4=[上海, 天津], k5=[大连, 杭州]}

        
        HashSet allCitys = new HashSet();
        allCitys.add("北京");
        allCitys.add("上海");
        allCitys.add("天津");
        allCitys.add("广州");
        allCitys.add("深圳");
        allCitys.add("成都");
        allCitys.add("杭州");
        allCitys.add("大连");
        HashSet selectBroadcasts = new HashSet<>();
        HashSet tempKeys = new HashSet<>();

        //创建指向最大城市数的key的引用,以及指向当前广播台的key
        String maxKey = null;

        
        while (allCitys.size() > 0){//只有长度不为0的时候才可以继续,否则就是已经选好了
            //每一次while maxKey都要置空
            maxKey = null;

            //从broadcastsAndCitys中依次取出key,经过循环赋值,得到maxKey
            for (String key: broadcastsAndCitys.keySet()){
                //因为tempKeys是针对每一个key的,所以每取得一个key就要清空一次
                tempKeys.clear();
                //给tempKeys赋值
                HashSet hashSet = broadcastsAndCitys.get(key);//!!!这里要重新创建一个集合去接收!!!
                tempKeys.addAll(hashSet);
                //tempKeys = broadcastsAndCitys.get(key);
                //让当前key和allCitys取交集,得其包括的城市数
                tempKeys.retainAll(allCitys);
                //给maxKey赋值
                if (tempKeys.size() > 0 &&
                        (maxKey == null || tempKeys.size() > broadcastsAndCitys.get(maxKey).size())){
                    //不管怎么着,得有城市才能赋值
                    //maxKey为空说明还没赋过值呢,就直接赋值
                    //tempKeys里面有东西,且东西的数目比当前maxKey指向的数目要多(没有等于,如果相等,maxKey就指向第一个)
                    maxKey = key;
                }
            }

            if (maxKey != null){
                //把选出来的maxKey加进去selectBroadcasts
                selectBroadcasts.add(maxKey);
                //把选出来的maxKey覆盖的城市从allCitys中去掉
                allCitys.removeAll(broadcastsAndCitys.get(maxKey));
            }else {
                //如果比较下来都没有一个合适的maxKey,而且allCitys.size()还可能>0,那么很遗憾,可能只能找到最接近需求的解
                break;
            }
        }

        System.out.println(selectBroadcasts);
    }
}

结果

{k1=[上海, 天津, 北京], k2=[广州, 北京, 深圳], k3=[成都, 上海, 杭州], k4=[上海, 天津], k5=[大连, 杭州]}
[k1, k2, k3, k5]
意外收获:addAll方法

addAll是传入一个List,将此List中的所有元素加入到当前List中

public class
Test {
    public static void main(String[] args) {
        HashMap> broadcastsAndCitys = new HashMap<>();
        HashSet test1 = new HashSet<>();
        test1.add("我");
        test1.add("是");
        test1.add("最");
        test1.add("帅");
        broadcastsAndCitys.put("k1",test1);

        //test3是要被交集的
        HashSet test3 = new HashSet<>();
        test3.add("我");

        //test2是保存交集的
        HashSet test2 = new HashSet<>();

        //test2把test1拿出来,与test3取交集,赋给test2
        test2 = broadcastsAndCitys.get("k1");
        test2.retainAll(test3);

        //结果test1变成了test2,就是取完交集的那个结果,这里就是打印1 因为只有一个交集
        System.out.println(broadcastsAndCitys.get("k1").size());
        //原因:test2把test1拿出来,意味着test2和test1指向了相同的位置,相同的内存空间

        //如果重新创建一个HashSet来保存test1,然后再与test3取交集
        HashSet test4 = broadcastsAndCitys.get("k1");
        test2.addAll(test4);//注意用addAll方法
        test2.retainAll(test3);

        //这里就是打印4 因为原来的没变
        System.out.println(broadcastsAndCitys.get("k1").size());
        //原因:test4在与test2发生关系的时候,用了addAll方法,这个方法是把test4的所有元素的内容加进去
        //此时test2相当于指向了另一块内存空间,其内容与test4是一样的
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/269965.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号