华为OD机试真题——生成哈夫曼树(2025B卷:100分)Java/python/JavaScript/C/C++/GO六种最佳实现

news2025/7/24 2:03:37

在这里插入图片描述

2025 B卷 100分 题型

本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!

本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》

华为OD机试真题《生成哈夫曼树》:


目录

    • 题目名称:生成哈夫曼树
      • 题目描述
    • Java
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 输入1:
        • 输入2:
        • 输入3:
      • 综合分析
    • python
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 输入1:
        • 输入2:
        • 输入3:
      • 综合分析
    • JavaScript
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析
    • C++
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 输入1:
        • 输入2:
        • 输入3:
      • 综合分析
    • C语言
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 输入1:
        • 输入2:
        • 输入3:
      • 综合分析
    • GO
      • 问题分析
      • 解题思路
      • 代码实现
      • 代码详细解析
      • 示例测试
        • 示例1输入:
        • 示例2输入:
        • 示例3输入:
      • 综合分析


题目名称:生成哈夫曼树


  • 知识点:哈夫曼树、优先队列
  • 时间限制:1秒
  • 空间限制:256MB
  • 限定语言:不限

题目描述

给定长度为 n 的无序数字数组,每个数字代表二叉树的叶子节点权值(所有值 ≥ 1)。请根据输入生成哈夫曼树,并输出其中序遍历结果。要求满足以下限制条件:

  1. 节点权值规则:左节点权值 ≤ 右节点权值,根节点权值为左右子节点权值之和。
  2. 高度规则:若左右节点权值相同,左子树高度 ≤ 右子树高度。

输入描述

  • 第一行为整数 n(表示叶子节点数量,1 ≤ n ≤ 1e5)。
  • 第二行为 n 个正整数,表示每个叶子节点的权值。

输出描述

  • 输出中序遍历结果,数值间以空格分隔。若无有效树,返回空数组(用例保证输入有效)。

示例
输入:

5  
5 15 40 30 10  

输出:

40 100 30 60 15 30 5 15 10  

说明

  • 生成的哈夫曼树带权路径最短,如示例中总路径长度为:40×1 + 30×2 + 15×3 + 5×4 + 10×4 = 205。
  • 中序遍历结果需满足左节点权值 ≤ 右节点,且权值相同时左子树高度更低。

补充说明

  • 哈夫曼树构造需通过优先队列(小顶堆)合并最小权值节点,直至只剩一个根节点。
  • 时间复杂度需为 O(n log n),空间复杂度 O(n)。

Java

问题分析

我们需要根据给定的权值数组构建哈夫曼树,并输出其中序遍历结果。哈夫曼树的构建需要满足:

  1. 权值规则:左节点的权值 ≤ 右节点的权值。
  2. 高度规则:权值相同时,左子树的高度 ≤ 右子树的高度。
  3. 高效构造:使用优先队列(小顶堆)合并最小权值节点,时间复杂度为 O(n log n)。

解题思路

  1. 优先队列初始化:将每个权值初始化为叶子节点,按权值从小到大排列,权值相同时按高度从小到大排列。
  2. 构建哈夫曼树
    • 每次从队列取出两个最小节点,合并为新节点。
    • 新节点的权值为子节点之和,高度为较大子树高度加一。
    • 根据权值规则和高度规则确定左右子节点顺序。
  3. 中序遍历:使用非递归方式遍历树,按左 → 根 → 右顺序收集权值。

代码实现

import java.util.*;

public class Main {
   
    static class Node {
   
        int weight;
        Node left;
        Node right;
        int height;

        // 叶子节点构造函数
        public Node(int weight) {
   
            this.weight = weight;
            this.height = 0; // 叶子节点高度为0
        }

        // 合并生成父节点的构造函数
        public Node(Node left, Node right) {
   
            this.left = left;
            this.right = right;
            this.weight = left.weight + right.weight;
            this.height = Math.max(left.height, right.height) + 1;
        }
    }

    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        List<Integer> weights = new ArrayList<>();
        for (int i = 0; i < n; i++) {
   
            weights.add(scanner.nextInt());
        }

        // 优先队列:按权值从小到大,权值相同时按高度从小到大
        PriorityQueue<Node> queue = new PriorityQueue<>((a, b) -> {
   
            if (a.weight != b.weight) {
   
                return a.weight - b.weight;
            } else {
   
                return a.height - b.height;
            }
        });

        // 初始化队列,所有叶子节点入队
        for (int w : weights) {
   
            queue.add(new Node(w));
        }

        // 合并节点,构建哈夫曼树
        while (queue.size() > 1) {
   
            Node left = queue.poll();
            Node right = queue.poll();
            Node parent = new Node(left, right); // 自动满足左 ≤ 右
            queue.add(parent);
        }

        // 中序遍历
        Node root = queue.poll();
        List<Integer> result = new ArrayList<>();
        Deque<Node> stack = new LinkedList<>();
        Node current = root;

        // 非递归中序遍历
        while (current != null || !stack.isEmpty()) {
   
            while (current != null) {
   
                stack.push(current);
                current = current.left;
            }
            current = stack.pop();
            result.add(current.weight);
            current = current.right;
        }

        // 输出结果
        StringBuilder sb = new StringBuilder();
        for (int num : result) {
   
            sb.append(num).append(" ");
        }
        if (sb.length() > 0) {
   
            sb.deleteCharAt(sb.length() - 1);
        }
        System.out.println(sb);
    }
}

代码详细解析

  1. Node 类

    • weight:节点权值。
    • leftright:左右子节点。
    • height:节点高度,叶子节点为0,父节点为子节点最大高度加一。
  2. 优先队列初始化

    • 自定义比较器,先按权值排序,权值相同时按高度排序。
    • 将所有叶子节点加入队列。
  3. 合并节点

    • 循环取出两个最小节点,合并为新节点。
    • 新节点的左右顺序由队列比较器自动保证(权值小者优先,权值相同高度小者优先)。
  4. 中序遍历

    • 使用栈模拟递归,按左 → 根 → 右顺序遍历所有节点。
    • 收集所有节点的权值到结果列表。
  5. 输出处理

    • 将结果列表转换为字符串格式,确保末尾无空格。

示例测试

输入1:
5  
5 15 40 30 10  

输出

40 100 30 60 15 30 5 15 10  

解析:合并顺序确保所有条件满足,中序遍历结果正确。

输入2:
2  
3 5  

输出

3 8 5  

解析:合并生成父节点8,中序遍历顺序为3 → 8 → 5。

输入3:
1  
5  

输出

5  

解析:单个叶子节点,直接输出自身权值。


综合分析

  1. 时间复杂度:O(n log n)。
    • 优先队列的插入和删除操作均为 O(log n),共执行 O(n) 次。
  2. 空间复杂度:O(n)。
    • 存储哈夫曼树需要 O(n) 空间,优先队列和中序遍历栈均为 O(n)。
  3. 优势
    • 高效合并:优先队列确保每次合并选择最小权值节点。
    • 自动排序:比较器自动处理权值和高度规则,确保树结构正确。
  4. 适用场景:大规模数据处理,符合题目要求的 O(n log n) 时间复杂度和 O(n) 空间复杂度。

python

问题分析

我们需要根据给定的权值数组构建哈夫曼树,并输出其中序遍历结果。哈夫曼树的构建需满足:

  1. 权值规则:左节点权值 ≤ 右节点权值。
  2. 高度规则:权值相同时,左子树高度 ≤ 右子树高度。
  3. 高效构造:使用优先队列(小顶堆)合并最小节点,时间复杂度为 O(n log n)。

解题思路

  1. 优先队列初始化:将每个权值初始化为叶子节点,按权值从小到大排列,权值相同时按高度从小到大排列。
  2. 构建哈夫曼树
    • 每次从队列取出两个最小节点,合并为新节点。
    • 新节点的权值为子节点之和,高度为较大子树高度加一。
  3. 中序遍历:使用栈模拟递归遍历,按左 → 根 → 右顺序收集权值。

代码实现

import heapq

class Node:
    def __init__(self, weight, left=None, right=None):
        self.weight = weight
        self.left = left
        self.right = right
        # 计算节点高度:叶子节点高度为0,父节点高度为子节点最大高度+1
        if left is None and right is None:
            self.height = 0
        else:
            self.height = max(left.height, right.height) + 1

    # 定义节点比较规则:先比权值,权值相同比高度
    def __lt__(self, other):
        if self.weight != other.weight:
            return self.weight < other.weight
        else:
            return self.height < other.height

def main():
    n = int(input())
    weights = list(map(int, input().split()))
    
    if n == 0:
        print("")
        return
    
    # 初始化优先队列
    heap = []
    for w in weights:
        heapq.heappush(heap, Node(w))
    
    # 合并节点直到只剩根节点
    while len(heap) > 1:
        left = heapq.heappop(heap)
        right = heapq.heappop(heap)
        # 创建父节点,自动满足左≤右的规则
        parent = Node(left.weight + right.weight, left, right)
        heapq.heappush(heap,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397841.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis最佳实践——性能优化技巧之监控与告警详解

Redis 在电商应用的性能优化技巧之监控与告警全面详解 一、监控体系构建 1. 核心监控指标矩阵 指标类别关键指标计算方式/说明健康阈值&#xff08;参考值&#xff09;内存相关used_memoryINFO Memory 获取不超过 maxmemory 的 80%mem_fragmentation_ratio内存碎片率 used_m…

R3GAN训练自己的数据集

简介 简介&#xff1a;这篇论文挑战了"GANs难以训练"的广泛观点&#xff0c;通过提出一个更稳定的损失函数和现代化的网络架构&#xff0c;构建了一个简洁而高效的GAN基线模型R3GAN。作者证明了通过合适的理论基础和架构设计&#xff0c;GANs可以稳定训练并达到优异…

【容器docker】启动容器kibana报错:“message“:“Error: Cannot find module ‘./logs‘

说明&#xff1a; 1、服务器数据盘挂了&#xff0c;然后将以前的数据用rsync拷贝过去&#xff0c;启动容器kibana服务&#xff0c;报错信息如下图所示&#xff1a; 2、可能是拷贝docker文件夹&#xff0c;有些文件没有拷贝过去&#xff0c;导致无论是给文件夹授权用户kibana或者…

C#里与嵌入式系统W5500网络通讯(4)

怎么样修改W5500里的socket收发缓冲区呢? 需要进行下面的工作,首先要了解socket缓冲区的作用,接着了解缓冲区的硬件资源, 最后就是要了解自己的需求,比如自己需要哪个socket的收发送缓冲区多大。 硬件的寄存器为: 这是 W5500 数据手册中关于 Sn_RXBUF_SIZE(Socket n …

Spring boot集成milvus(spring ai)

服务器部署Milvus Run Milvus with Docker Compose (Linux) milvus版本可在docker-compose.yml中进行image修改 启动后&#xff0c;docker查看启动成功 spring boot集成milvus 参考了这篇文章 Spring AI开发RAG示例&#xff0c;理解RAG执行原理 但集成过程中遇到了一系列…

Visual Studio+SQL Server数据挖掘

这里写自定义目录标题 工具准备安装Visual studio 2017安装SQL Server安装SQL Server Management Studio安装analysis service SSMS连接sql serverVisual studio新建项目数据源数据源视图挖掘结构部署模型设置挖掘预测 部署易错点 工具准备 Visual studio 2017 analysis servi…

通过阿里云服务发送邮件

通过阿里云服务发送邮件 1. 整体描述2. 方案选择2.1 控制台发送2.2 API接口接入2.3 SMTP接口接入2.4 结论 3. 前期工作3.1 准备工作3.2 配置工作3.3 总结 4. 收费模式4.1 免费额度4.2 资源包4.3 按量付费 5. Demo开发5.1 选择SMTP服务器5.2 pom引用5.3 demo代码5.4 运行结果 6 …

Vad-R1:通过从感知到认知的思维链进行视频异常推理

文章目录 速览摘要1 引言2 相关工作视频异常检测与数据集视频多模态大语言模型具备推理能力的多模态大语言模型 3 方法&#xff1a;Vad-R13.1 从感知到认知的思维链&#xff08;Perception-to-Cognition Chain-of-Thought&#xff09;3.2 数据集&#xff1a;Vad-Reasoning3.3 A…

黑马Java面试笔记之MySQL篇(事务)

一. 事务的特性 事务的特性是什么&#xff1f;可以详细说一下吗&#xff1f; 事务是一组操作的集合&#xff0c;他是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失…

群辉(synology)NAS老机器连接出现网页端可以进入,但是本地访问输入一样的账号密码是出现错误时解决方案

群辉&#xff08;synology&#xff09;NAS老机器连接出现网页端可以进入&#xff0c;但是本地访问输入一样的账号密码是出现错误时解决方案 老机器 装的win7 系统 登入后端网页端的时候正常&#xff0c;但是本地访问登入时输入登入网页端一样的密码时候出现问题解决方案 1.登…

【深度学习】实验四 卷积神经网络CNN

实验四 卷积神经网络CNN 一、实验学时&#xff1a; 2学时 二、实验目的 掌握卷积神经网络CNN的基本结构&#xff1b;掌握数据预处理、模型构建、训练与调参&#xff1b;探索CNN在MNIST数据集中的性能表现&#xff1b; 三、实验内容 实现深度神经网络CNN。 四、主要实验步…

实现一个免费可用的文生图的MCP Server

概述 文生图模型为使用 Cloudflare Worker AI 部署 Flux 模型&#xff0c;是参照视频https://www.bilibili.com/video/BV1UbkcYcE24/?spm_id_from333.337.search-card.all.click&vd_source9ca2da6b1848bc903db417c336f9cb6b的复现Cursor MCP Server实现是参照文章https:/…

【手搓一个原生全局loading组件解决页面闪烁问题】

页面闪烁效果1 页面闪烁效果2 封装一个全局loading组件 class GlobalLoading extends HTMLElement {constructor() {super();this.attachShadow({ mode: open });}connectedCallback() {this.render();this.init();}render() {this.shadowRoot.innerHTML <style>.load…

CSS基础巩固-基础-选择

目录 CSS是如何工作的&#xff1f; 当浏览器遇到无法解析的CSS代码时 如何导入CSS样式&#xff1f; 改变元素的默认样式 选择 前缀符号&#xff08;后面会具体介绍&#xff09; 优先级 同时应用样式到多个类上 属性选择器 伪类 伪元素 关系选择器 后代选择器 子代…

一种在SQL Server中传递多行数据的方法

这是一种比较偷懒的方法&#xff0c;其实各种数据库对Json 支持的很好。sql server 、oracle都不错。所以可以直接传json declare 这是一个json varchar(max) set 这是一个json{"data":[{"code":"1","name":"啥1"},{"…

【Docker 从入门到实战全攻略(一):核心概念 + 命令详解 + 部署案例】

1. 是什么 Docker 是一个用于开发、部署和运行应用程序的开源平台&#xff0c;它使用 容器化技术 将应用及其依赖打包成独立的容器&#xff0c;确保应用在不同环境中一致运行。 2. Docker与虚拟机 2.1 Docker&#xff08;容器化&#xff09; 容器化是一种轻量级的虚拟化技术…

github 提交失败,连接不上

1. 第一种情况&#xff0c;开了加速器&#xff0c;导致代理错误 删除hosts文件里相关的github代理地址 2. 有些ip不支持22端口连接,改为443连接 ssh -vT gitgithub.com // 命令执行结果 OpenSSH_for_Windows_9.5p1, LibreSSL 3.8.2 debug1: C…

系统架构设计师(一):计算机系统基础知识

系统架构设计师&#xff08;一&#xff09;&#xff1a;计算机系统基础知识 引言计算机系统概述计算机硬件处理器处理器指令集常见处理器 存储器总线总线性能指标总线分类按照总线在计算机中所处的位置划分按照连接方式分类按照功能分类 接口接口分类 计算机软件文件系统文件类…

清理 pycharm 无效解释器

1. 起因&#xff0c; 目的: 经常使用 pycharm 来调试深度学习项目&#xff0c;每次新建虚拟环境&#xff0c;都是显示一堆不存在的名称&#xff0c;删也删不掉。 总觉得很烦&#xff0c;是个痛点。决定深入研究一下。 2. 先看效果 效果是能行&#xff0c;而且清爽多了。 3. …

手机如何压缩文件为 RAR 格式:详细教程与工具推荐

在如今这个数字化时代&#xff0c;手机已经成为我们生活中不可或缺的工具。随着我们使用手机的频率越来越高&#xff0c;手机中的文件也越来越多&#xff0c;照片、视频、文档等各种类型的文件不断占据着手机的存储空间。 据统计&#xff0c;普通用户的手机存储空间中&#xf…