题解 | #【模板】哈夫曼编码# ✅✅✅不构建哈夫曼树求解

【模板】哈夫曼编码

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

关键词:哈夫曼编码 / 贪心算法

核心思想无需构建完整的哈夫曼树,可以利用贪心策略和优先队列(最小堆),直接算哈夫曼编码的最小成本WPL(编码后字符串的最短长度)。

解题步骤

  1. 输入和初始化:读取每个字符的出现次数,并将其存入一个优先队列(最小堆)中。其中 greater<> 比较器确保队列内元素降序排列。
  2. 合并操作:只要优先队列中剩余的元素大于1,就进行以下操作:
  3. 从优先队列中取出两个最小的元素a和b。
  4. 计算这两个元素合并后的成本a + b,并将该成本累加到结果变量res中。
  5. 将合并后的元素a + b重新压入优先队列。
  6. 输出结果:当优先队列中只剩下一个元素时,res即为所有合并操作的总成本(编码后字符串的最短长度)。

算法复杂度:时间复杂度O(nlogn),属于此类问题的最低时间复杂度;空间复杂度O(n)。

#include <iostream>
#include <queue>
using namespace std;

int main() {
    int n, x;
    cin >> n;
    // 定义一个优先队列,存储字符出现的次数
    // 使用greater<>比较器,使得队列顶部始终是最小的元素
    priority_queue<long long, vector<long long>, greater<>> que;
    for (int i = 0; i < n; ++i) {
        cin >> x;
        que.push(x);
    }

    long long res = 0; // 初始化结果变量res,用于累加所有合并操作的成本
    // 当优先队列中剩余元素大于1时,继续合并操作
    while (que.size() > 1) {
        // 从优先队列中取出两个最小的元素
        long long a = que.top();
        que.pop(); // 第一个最小元素
        long long b = que.top();
        que.pop(); // 第二个最小元素

        // 计算这两个元素合并后的成本,并累加到res中
        res += a + b;
        // 将合并后的元素重新压入优先队列
        que.push(a + b);
    }

    // 最终的res就是编码后字符串的最短长度
    cout << res << endl;
    return 0;
}

}

全部评论

相关推荐

牛客771574427号:恭喜你,华杰
点赞 评论 收藏
分享
10-24 13:36
门头沟学院 Java
Zzzzoooo:更新:今天下午有hr联系我去不去客户端,拒了
点赞 评论 收藏
分享
评论
1
收藏
分享
牛客网
牛客企业服务