華為OD機試真題——生成哈夫曼樹(2025A卷:100分)Java/python/JavaScript/C/C++/GO六種最佳實現

在這里插入圖片描述

2025 A卷 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 heapqclass Node:def __init__(self, weight, left=None, right=None):self.weight = weightself.left = leftself.right = right# 計算節點高度:葉子節點高度為0,父節點高度為子節點最大高度+1if left is None and right is None:self.height = 0else:self.height = max(left.height, right.height) + 1# 定義節點比較規則:先比權值,權值相同比高度def __lt__(self, other):if self.weight != other.weight:return self.weight < other.weightelse:return self.height < other.heightdef 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.pswp.cn/diannao/85478.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85478.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85478.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

房屋租賃系統 Java+Vue.js+SpringBoot,包括房屋類型、房屋信息、預約看房、合同信息、房屋報修、房屋評價、房主管理模塊

房屋租賃系統 JavaVue.jsSpringBoot&#xff0c;包括房屋類型、房屋信息、預約看房、合同信息、房屋報修、房屋評價、房主管理模塊 百度云盤鏈接&#xff1a;https://pan.baidu.com/s/1KmwOFzN9qogyaLQei3b6qw 密碼&#xff1a;l2yn 摘 要 社會的發展和科學技術的進步&#xf…

Unity 中 Update、FixedUpdate 和 LateUpdate 的區別及使用場景

在Unity開發中,Update、FixedUpdate 和 LateUpdate 是生命周期函數中最常見也最容易混淆的一組。 一、調用時機 方法名調用頻率調用時機說明Update()每幀調用一次跟隨幀率(幀率高則調用頻率高)FixedUpdate()固定時間間隔調用默認每 0.02 秒執行一次LateUpdate()每幀調用一次…

Docker鏡像之windows系統

https://github.com/dockur/windows 在 Docker 容器中運行 Windows 功能 ISO 下載器KVM 加速基于網頁的查看器 使用方法 啟動容器并通過瀏覽器連接到端口 8006。整個安裝過程將全自動完成&#xff0c;無需手動干預。當桌面界面出現時&#xff0c;表示 Windows 安裝已完成&a…

C# 用戶控件(User Control)詳解:創建、使用與最佳實踐

在C#應用程序開發中&#xff0c;用戶控件&#xff08;User Control&#xff09;是一種強大的工具&#xff0c;它允許開發者將多個標準控件組合成一個可復用的自定義組件。無論是Windows Forms還是WPF&#xff0c;用戶控件都能顯著提高UI開發的效率&#xff0c;減少重復代碼&…

pikachu靶場通關筆記09 XSS關卡05-DOM型XSS-X

目錄 一、XSS 二、DOM型XSS 三、源碼分析 1、打開DOM-X型XSS關卡 2、XSS探測 3、源碼分析 四、滲透實戰 1、Payload1 2、Payload2 3、Payload3 五、DOM型XSS與DOM-X型XSS區別 本系列為通過《pikachu靶場通關筆記》的XSS攻擊關卡(共10關&#xff09;滲透集合&#xf…

湖北理元理律所:企業債務重組中的“法律緩沖帶”設計

一、擔保鏈危機的法律拆解技術 中小企業債務困局多源于擔保鏈蔓延。本所處理某制造企業案例時&#xff0c;運用三層法律工具阻斷風險傳導&#xff1a; 1. 主合同審查 → 發現銀行擅自變更借款用途 → 援引《民法典》第695條解除擔保 2. 股東責任切割 → 證明企業財產獨立 …

調整數據集的方法

我們對worldquant中的數據&#xff0c; 對數據頻率怎么算 在 WorldQuant 平臺中&#xff0c;數據更新頻率是影響量化策略有效性、回測準確性和實盤交易表現的核心因素之一。它決定了數據的時效性和連續性&#xff0c;直接關系到策略能否捕捉市場動態、應對突發事件或適應不同…

[Linux] Linux 系統從啟動到驅動加載

Linux 系統從啟動到驅動加載 文章目錄 Linux 系統從啟動到驅動加載一、硬件上電與 BIOS/UEFI 階段1. 1 硬件上電初始化1.2 BIOS/UEFI執行過程1.3 Bootloader加載細節 二、Bootloader 階段三、Linux 內核初始化3.1 架構相關初始化&#xff08;setup_arch&#xff09;3.2 核心子系…

Spring Boot DevTools 熱部署

在Spring Boot項目中加入 spring-boot-devtools 熱部署依賴啟動器后&#xff0c;通常不需要手動重啟項目即可讓更改生效。spring-boot-devtools 的核心特性之一就是自動重啟或熱加載。 Spring Boot DevTools 熱部署關鍵知識點 &#x1f525; 目的&#xff1a;spring-boot-devt…

uni-app學習筆記十五-vue3頁面生命周期(二)

onShow&#xff1a;用于監聽頁面顯示&#xff0c;頁面每次出現在屏幕上都觸發&#xff0c;包括從下級頁面點返回露出當前頁面&#xff1b; onHide:監聽頁面隱藏&#xff0c;當離開當前頁面時觸發。 示例代碼&#xff1a; <template><view>姓名&#xff1a;{{nam…

LIKE ‘%xxx%‘ 和 LIKE ‘xxx%‘ 的索引影響分析

LIKE ‘%xxx%’ 和 LIKE ‘xxx%’ 的索引影響分析 一、基礎概念解析 1.1 LIKE操作符的工作原理 LIKE是SQL中用于模式匹配的操作符,支持兩種通配符: %:匹配任意數量字符(包括零個字符)_:匹配單個字符go專欄:https://duoke360.com/tutorial/path/golang 1.2 數據庫索引…

【軟件測試】測試框架(unittest/pytest)

本文介紹了Python 中最常用的兩個測試框架&#xff1a;unittest 和 pytest&#xff0c;幫助你編寫更規范、可維護的自動化測試用例。 一、unittest 框架 unittest 是 Python 內置的標準庫&#xff0c;無需額外安裝&#xff0c;適合初學者入門。它借鑒了 JUnit 的設計理念&…

麒麟信安安裝谷歌瀏覽器

參考文檔 麒麟信安系統Chrome離線安裝包&#xff1a;高效便捷的瀏覽器解決方案-CSDN博客 項目文件預覽 - 麒麟信安系統Chrome離線安裝包:本倉庫提供了一個適用于麒麟信安系統的Chrome瀏覽器離線安裝包。該安裝包包含了所有必要的依賴文件&#xff0c;并且已經對系統中已有的依…

Wireshark 使用教程:讓抓包不再神秘

一、什么是 tshark&#xff1f; tshark 是 Wireshark 的命令行版本&#xff0c;支持幾乎所有 Wireshark 的核心功能。它可以用來&#xff1a; 抓包并保存為 pcap 文件 實時顯示數據包信息 提取指定字段進行分析 配合 shell 腳本完成自動化任務 二、安裝與驗證 Kali Linux…

從0到1:多醫院陪診小程序開發筆記(上)

概要設計 醫院陪診預約小程序&#xff1a;隨著移動互聯網的普及&#xff0c;越來越多的醫院陪診服務開始向線上轉型, 傳統的預約方式往往效率低下&#xff0c;用戶需耗費大量時間進行電話預約或現場排隊&#xff0c;陪診服務預約小程序集多種服務于一體&#xff0c;可以提高服…

定時任務:springboot集成xxl-job-core(二)

定時任務實現方式&#xff1a; 存在的問題&#xff1a; xxl-job的原理&#xff1a; 可以根據服務器的個數進行動態分片&#xff0c;每臺服務器分到的處理數據是不一樣的。 1. 多臺機器動態注冊 多臺機器同時配置了調度器xxl-job-admin之后&#xff0c;執行器那里會有多個注…

Unity使用Lua框架和C#框架開發游戲的區別

在Unity中使用Lua框架和C#框架開發游戲有顯著的區別&#xff0c;主要體現在性能、開發效率、熱更新能力、維護成本等方面。 1. 語言類型與設計目標 維度LuaC#類型動態類型、解釋型腳本語言靜態類型、編譯型面向對象語言設計初衷輕量級嵌入、配置和擴展宿主程序通用開發&#…

高精度文檔解析利器:Mistral OCR 全面解析與技術應用

目錄 &#x1f680; 高精度文檔解析利器&#xff1a;Mistral OCR 全面解析與技術應用 一、什么是 Mistral OCR&#xff1f; 二、Mistral OCR 的核心特點 ? 1. 支持復雜文檔結構解析 ? 2. 高識別精度 ? 3. 與 AI 系統深度集成 ? 4. 可擴展性與容錯能力 三、技術原理…

騰訊云開發者社區文章內容提取免費API接口教程

接口簡介&#xff1a; 提取指定騰訊云開發者社區文章內容。本接口僅做內容提取&#xff0c;未經作者授權請勿轉載。 請求地址&#xff1a; https://cn.apihz.cn/api/caiji/tencent.php 請求方式&#xff1a; POST或GET。 請求參數&#xff1a; 【名稱】【參數】【必填】【說…

【項目】在線OJ(負載均衡式)

目錄 一、項目目標 二、開發環境 1.技術棧 2.開發環境 三、項目樹 目錄結構 功能邏輯 編寫思路 四、編碼 1.complie_server 服務功能 代碼藍圖 開發編譯功能 日志功能 ?編輯 測試編譯模塊 開發運行功能 設置運行限制 jsoncpp 編寫CR 如何生成唯一文件名 …