時間限制:1秒 空間限制:32768K 熱度指數:629
本題知識點: 貪心
題目描述:
請設計一個算法,給一個字符串進行二進制編碼,使得編碼後字符串的長度最短。
輸入描述
每組數據一行,爲待編碼的字符串。保證字符串長度小於等於1000。
輸出描述
一行輸出最短的編碼後長度。
輸入例子
MT-TECH-TEAM
輸出例子
33
解題思路(以輸入例子爲例)
- 統計各個字符出現的個數,如下:
M(2), T(3), E(2), C(1), H(1), A(1), -(2) - 畫出哈夫曼樹,如下:
- 發現編碼後字符串的長度等於:各個非葉子結點值之和(2+3+5+4+7+12)
- 利用這個,用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);
}
}
}