题解 | 哈夫曼编码 -最小堆-优先队列

哈夫曼编码

https://www.nowcoder.com/practice/4c0419eb07c840ca8402e4f2a52cfd49

import sys

# for line in sys.stdin:
#     a = line.split()
#     print(int(a[0]) + int(a[1]))


"""
 哈夫曼编码
 https://blog.csdn.net/xyy1028/article/details/139965597
 
 哈夫曼编码的核心思想: 
 高频字符用短编码 ,低频符号用长编码,从而最小化总编码长度。
算法思路:
1.优先队列(最小堆)
将所有字符的频率存入最小堆,每次取出两个最小的频率合并
直到对重只剩下一个节点。
合并时,记录每次合并的权值之和,这些权值的累加为最小编码长度。
2. 计算最短编码长度
  每次合并两个最小频率a和b ,生成新的节点a+b ,并将a+b 重新
  放入堆中。
  总编码长度=所有非叶子节点的权值之和(每次合并的a+b 的累加)。
示例解析‌
‌输入‌:n = 3,a = [1, 2, 3]
‌步骤‌:
初始堆:[1, 2, 3]
合并 1 和 2 → 3(总长度 +3),堆变为 [3, 3]
合并 3 和 3 → 6(总长度 +6),堆变为 [6]
‌总长度‌ = 3 + 6 = 9(与示例一致)。

复杂度: 
时间复杂度:O(n log n ) 每次堆操作 o(log n)  ,共 n次。
空间复杂度: O(n) 堆存储
关键点‌
‌堆优化‌:直接使用 heapq 模块,避免手动实现堆。
‌贪心策略‌:每次合并最小的两个节点,确保总编码长度最小化。
‌边界情况‌:当 n = 1 时,无需合并,总长度为 0(但题目保证 a_i ≥ 1,故 n ≥ 1 时至少有一个字符)。
"""
import heapq
def solve():
    n =int(input())
    a= list(map(int,input().split()))
    total=0
    heapq.heapify(a)
    while len(a)>1:
        x= heapq.heappop(a)
        y=heapq.heappop(a)
        cost=x+y
        total+=cost
        heapq.heappush(a,cost)
    print(total)

solve()

全部评论

相关推荐

zzzzhz:兄弟你先猛猛投简历至少三百家,能约到面试就去面。最近可以速成智能小车,智慧家居烂大街的项目,不需要自己写,只需要把里面的代码讲解看明白就行。把其中涉及到的八股文都拿出来单独背一下,我去年找工作就一个智能小车智慧家居找了10k差不多。
点赞 评论 收藏
分享
牛客83700679...:简历抄别人的,然后再投,有反馈就是简历不行,没反馈就是学历不行,多投多改只要技术不差机会总会有的
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务