时间限制: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);
}
}
}