2022-6-10 真题练习

MT7 字符编码
 
 
warning 校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。

描述

请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。
 
数据范围:字符串长度满足 1 < n \le 1000 \1<n1000  ,本题有多组输入

输入描述:

每组数据一行,为待编码的字符串。保证字符串长度小于等于1000。

输出描述:

一行输出最短的编码后长度。
 1 import java.util.HashMap;
 2 import java.util.Map;
 3 import java.util.PriorityQueue;
 4 import java.util.Scanner;
 5 
 6 public class Main {
 7     static class TreeNode{
 8         TreeNode left,right;
 9         int weight;
10         Character c;
11         TreeNode(int w,char c){
12             weight=w;
13             this.c=c;
14         }
15     }
16     static int ans;
17     public static void main(String[] args) {
18         Scanner sc = new Scanner(System.in);
19         while (sc.hasNext()){
20             String s=sc.nextLine();
21             Map<Character,Integer> map=new HashMap();
22             for (int i=0;i<s.length();i++){
23                 map.put(s.charAt(i),map.getOrDefault(s.charAt(i),0)+1);
24             }
25             PriorityQueue<TreeNode> queue=new PriorityQueue<>((a,b)->(a.weight- b.weight));
26             for (Map.Entry<Character, Integer> entry : map.entrySet()) {
27                 queue.offer(new TreeNode(entry.getValue(),entry.getKey()));
28             }
29             while (queue.size()>=2){
30                 TreeNode n1=queue.poll();
31                 TreeNode n2=queue.poll();
32                 TreeNode node=new TreeNode(n1.weight+n2.weight,Character.MIN_VALUE);
33                 node.left=n1;
34                 node.right=n2;
35                 queue.offer(node);
36             }
37             TreeNode root=queue.poll();
38             ans=0;
39             dfs(root,map,0);
40             System.out.println(ans);
41         }
42 
43     }
44 
45     static public void dfs(TreeNode root,Map<Character,Integer> map,int depth){
46         if (root==null) {
47             return;
48         }
49         if (map.containsKey(root.c)){
50             ans+=map.get(root.c)*depth;
51         }
52         dfs(root.left,map,depth+1);
53         dfs(root.right,map,depth+1);
54     }
55 }

思路:编码最佳选择最小生成树,即哈夫曼树。先用hashmap记录不同字符的频率。

再用优先队列构造哈夫曼树:每次挑两个权重最小的合并,将权重和作为新的节点加入到队列中,直到剩下根节点。

深度遍历所有节点,记录节点的深度来计算编码的长度。

posted on 2022-06-10 21:09  阿ming  阅读(46)  评论(0)    收藏  举报

导航