美团点评2016研发题目-[编程题-美团] 字符编码

[编程题] 字符编码

时间限制:1秒

空间限制:32768K

请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。
输入描述:
每组数据一行,为待编码的字符串。保证字符串长度小于等于1000。
输出描述:
一行输出最短的编码后长度。
输入例子1:
MT-TECH-TEAM
输出例子1:
33

1.将字符串转为字符数组,遍历统计每个字符出现的次数,放入hash表中
2.创建节点TreeNode,放入一个优先队列
3.构建哈夫曼树合并两个权重最小的节点,直到只剩下根节点root
4.带着深度遍历树,计算长度和 
注意:‘-’也是字符,应该计算在内

import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		while (input.hasNext()) {
			String s = input.nextLine();
			int result = hafuman(s);
			System.out.println(result);
		}
	}

	public static int hafuman(String s) {
		char[] chars = s.toCharArray();
		// hash表存放每个字符和出现的次数
		Map<Character, Integer> hash = new HashMap<>();
		for (int i = 0; i < chars.length; i++) {
			if (hash.containsKey(chars[i])) {
				hash.put(chars[i], hash.get(chars[i]) + 1);
			} else {
				hash.put(chars[i], 1);
			}
		}
		//System.out.println(hash);
		// 优先队列(最小推),每次能得到weigh最小的node
		Queue<TreeNode> q = new PriorityQueue<>(hash.size(), new Comparator<TreeNode>() {
			@Override
			public int compare(TreeNode o1, TreeNode o2) {
				return Integer.compare(o1.weight, o2.weight);
			}
		});
		for (Map.Entry<Character, Integer> entry : hash.entrySet()) {
			q.offer(new TreeNode(entry.getValue(), entry.getKey()));
		}
		//赫夫曼编码,注意size()
		while (q.size() > 1) {
			// 弹出两个最小的,合并为一个node
			TreeNode left = q.poll();
			TreeNode right = q.poll();
			TreeNode father = new TreeNode(left.weight + right.weight);
			father.left = left;
			father.right = right;
			q.offer(father);
		}
		//q的最后一个元素就是root(最大的)
		TreeNode root = q.poll();
		// 计算长度 
		return valLength(root, 0);
	}

	public static int valLength(TreeNode node, int depth) {
		if (node == null)
			return 0;// 仅计算ch有值的
		return (node.ch == null ? 0 : node.weight) * depth + valLength(node.left, depth + 1)
				+ valLength(node.right, depth + 1);
	}

	static class TreeNode {
		//权重,出现次数
		int weight;
		// 如果是初始字符,则ch为字符,如果是合并的,则为null
		Character ch;
		TreeNode left;
		TreeNode right;

		public TreeNode(int weight) {
			this.weight = weight;
		}

		public TreeNode(int weight, Character ch) {
			this.weight = weight;
			this.ch = ch;
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值