Java 數據結構與算法系列精講之貪心算法

概述

從今天開始, 小白我將帶大傢開啟 Java 數據結構 & 算法的新篇章.

貪心算法

貪心算法 (Greedy Algorithm) 指的是在每一步選擇中都采取在當前狀態下最好或最優的選擇, 從而希望導致結果是最好或最優的算法. 貪心算法鎖得到的結果不一定是最優的結果, 但是都是相對近似最優的結果.

貪心算法的優缺點:

  • 優點: 貪心算法的代碼十分簡單
  • 缺點: 很難確定一個問題是否可以用貪心算法解決

電臺覆蓋問題

假設存在以下的廣播臺, 以及廣播臺可以覆蓋的地區:

廣播臺 覆蓋地區
K1 北京, 上海, 天津
K2 北京, 廣州, 深圳
K3 上海, 杭州, 成都
K4 上海, 天津
K5 杭州, 大連

貪心算法的核心思想:

  • 把所有需要覆蓋的地區取集合
  • 從電臺中取覆蓋集合中地區最多的一個
  • 集合中去除已覆蓋地區, 繼續匹配

代碼實現

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

public class 貪心算法 {

    // 集合, 存放廣播臺
    static HashMap<String, HashSet<String>> broadcasts = new HashMap<>();

    // 集合, 存放地區
    static HashSet<String> areas = new HashSet<String>();

    // 貪心算法
    public static ArrayList<String> Greedy() {

        // 創建數組存放結果
        ArrayList<String> selects = new ArrayList<>();

        // 循環直至地區都覆蓋
        while (areas.size() != 0) {

            // 存放交集最大的廣播臺
            String maxKey = null;

            // 存放交集最大的值
            int maxKeySize = 0;

            // 遍歷每個剩餘電臺
            for (String key : broadcasts.keySet()) {

                // 取出交集個數
                int currSize = getRetainSize(key);

                // 替換當前最大
                if (currSize > 0 && currSize > maxKeySize) {
                    maxKey = key;
                    maxKeySize = currSize;
                }
            }


            // 添加廣播臺到結果
            selects.add(maxKey);

            // 移除廣播臺
            areas.removeAll(broadcasts.get(maxKey));
        }

        return selects;
    }

    // 剩餘數量
    public static int getRetainSize(String key) {

        // 如果為空返回0
        if (key == null) return 0;

        // 存放key對應的地區集合
        HashSet<String> tempSet = new HashSet<>();

        // 取key對應的地區
        tempSet.addAll(broadcasts.get(key));

        // 取交集
        tempSet.retainAll(areas);

        return tempSet.size();
    }

    public static void main(String[] args) {

//        | K1 | 北京, 上海, 天津 |
//        | K2 | 北京, 廣州, 深圳 |
//        | K3 | 上海, 杭州, 成都 |
//        | K4 | 上海, 天津 |
//        | K5 | 杭州, 大連 |


        // 創建廣播臺
        HashSet<String> K1 = new HashSet<>(Arrays.asList("北京", "上海", "天津"));
        HashSet<String> K2 = new HashSet<>(Arrays.asList("北京", "廣州", "深圳"));
        HashSet<String> K3 = new HashSet<>(Arrays.asList("上海", "杭州", "成都"));
        HashSet<String> K4 = new HashSet<>(Arrays.asList("上海", "天津"));
        HashSet<String> K5 = new HashSet<>(Arrays.asList("杭州", "大連"));

        // 加入map
        broadcasts.put("K1", K1);
        broadcasts.put("K2", K2);
        broadcasts.put("K3", K3);
        broadcasts.put("K4", K4);
        broadcasts.put("K5", K5);

        areas.addAll(K1);
        areas.addAll(K2);
        areas.addAll(K3);
        areas.addAll(K4);
        areas.addAll(K5);

        // 調試輸出
        System.out.println(broadcasts);
        System.out.println(areas);

        ArrayList<String> result = Greedy();
        System.out.println(result);
    }
}

到此這篇關於Java 數據結構與算法系列精講之貪心算法的文章就介紹到這瞭,更多相關Java 貪心算法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: