【校招筆試】字符編碼(哈夫曼樹)

時間限制:1秒 空間限制:32768K 熱度指數:629
本題知識點: 貪心

題目描述:

請設計一個算法,給一個字符串進行二進制編碼,使得編碼後字符串的長度最短。

輸入描述

每組數據一行,爲待編碼的字符串。保證字符串長度小於等於1000。

輸出描述

一行輸出最短的編碼後長度。

輸入例子

MT-TECH-TEAM

輸出例子

33


解題思路(以輸入例子爲例)

  1. 統計各個字符出現的個數,如下:
    M(2), T(3), E(2), C(1), H(1), A(1), -(2)
  2. 畫出哈夫曼樹,如下:
    這裏寫圖片描述
  3. 發現編碼後字符串的長度等於:各個非葉子結點值之和(2+3+5+4+7+12)
  4. 利用這個,用HashMap存字符出現的個數,PriorityQueue優先隊列選出兩個最小的結點值

代碼

import java.util.*;

//比較器(沒有用)
class Comparators {
    public static Comparator getComparator() {
        return new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof Integer) {
                    return compare( (Integer) o1, (Integer) o2);
                } else return 1;
            }

            public int compare(Integer s1, Integer s2) {
                return s2-s1;
            }

        };
    }

}
public class Main {
    /*
        測試代碼
     */
    public static void main(String []args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
            String str = sc.nextLine();
            HashMap<Character, Integer> map = new HashMap<Character, Integer>();
            for(int i = 0; i < str.length(); i++) {
                Character c = str.charAt(i);
                if (map.containsKey(c)) {
                    map.put(c, map.get(c)+1);
                } else {
                    map.put(c, 1);
                }
            }
            PriorityQueue<Integer> queue = new PriorityQueue<Integer>();
            for(Character i : map.keySet()) {
                queue.add(map.get(i));
            }
            int ans = 0;
            while(!queue.isEmpty()) {
                int num1 = queue.poll();
                int num2 = queue.poll();
                ans += (num1+num2);
                if(!queue.isEmpty())queue.add(num1+num2);
            }
            System.out.println(ans);
        }

    }
}
發佈了122 篇原創文章 · 獲贊 32 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章