華為OD機試 - 創建二叉樹(Java 2024 E卷 200分)

題目描述

給定一系列樹狀結構操作的問題,通過 Q 次查詢還原樹結構并輸出結果。題目要求實現一個類 Solution,其方法 recoverTree 需要根據輸入的操作數組 operations 還原樹的結構,并返回樹的根節點。每個操作 operations[i] = [height, index] 表示在高度為 height 的位置插入一個索引為 index 的節點。

  • 樹節點定義

    • 每個節點 node 存在左子節點,則初始為 null
    • 每個節點 node 存在右子節點,則初始為 null
    • 每個節點存儲一個高度值 height 和索引值 index
  • 輸入要求

    • heightindex 初始為 0,并按計數遞增。
    • index 存儲節點的創建順序。
  • 注意事項

    • 輸入用例保證每次操作對應的節點已經存在。
    • 控制臺輸出的內容是根據還原后的樹根節點,按照層次遍歷方式 Q 次查詢打印的結果。

輸入輸出示例

示例 1:
輸入: operations = [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]
輸出: [0, 0, 1, 1, 0]
解釋:

  • [0, 0]:創建高度 0,索引 0 的節點,作為根節點。
  • [0, 1]:創建高度 0,索引 1 的節點,插入到根節點的左子樹(因為高度相同,按索引順序)。
  • [1, 1]:創建高度 1,索引 1 的節點,插入到根節點的右子樹(高度更高)。
  • [1, 0]:創建高度 1,索引 0 的節點,插入到根節點的左子樹(高度更高)。
  • [0, 0]:查詢高度 0,索引 0 的節點,返回其值 0。

示例 2:
輸入: operations = [[-1, 0], [1, 3], [null, 2]]
輸出: [-1, 0, 1, 3, null, 2]
解釋:

  • [-1, 0]:創建高度 -1,索引 0 的節點,作為根節點。
  • [1, 3]:創建高度 1,索引 3 的節點,插入到根節點的右子樹(高度更高)。
  • [null, 2]:查詢高度 null,索引 2 的節點,返回 null。

解題思路

問題分析

題目要求根據一系列操作還原一棵樹,并通過查詢返回指定節點的值。核心在于:

  1. 樹的構建:根據 operations 數組中的 [height, index] 創建節點并插入樹中。
  2. 插入規則:高度決定節點的層級,索引決定插入順序。
  3. 查詢操作:根據 [height, index] 找到對應節點并返回其值。
算法選擇
  1. 樹結構:使用二叉樹結構存儲節點,每個節點包含 heightindex,并有左右子節點。
  2. 插入規則
    • 如果高度相同,優先插入到左子樹。
    • 如果高度更高,優先插入到右子樹。
    • 如果高度更低,插入到左子樹。
  3. 層次遍歷:在查詢時,通過層次遍歷找到目標節點。
步驟詳解
  1. 定義節點類:包含 heightindex、左子節點和右子節點。
  2. 構建樹
    • 遍歷 operations,對于每個操作:
      • 如果 height 不為 null,創建新節點并插入樹中。
      • 插入時,比較 heightindex,決定插入到左子樹還是右子樹。
  3. 查詢節點
    • 遍歷 operations,對于查詢操作(heightnull),通過層次遍歷找到目標節點并返回其值。
  4. 返回結果:按照查詢順序返回結果數組。

代碼實現

Java
class TreeNode {int height;int index;TreeNode left;TreeNode right;TreeNode(int height, int index) {this.height = height;this.index = index;this.left = null;this.right = null;}
}class Solution {public int[] recoverTree(int[][] operations) {TreeNode root = null;List<Integer> result = new ArrayList<>();// 構建樹for (int[] op : operations) {int height = op[0];int index = op[1];// 如果 height 不為 null,插入節點if (height != Integer.MIN_VALUE) {TreeNode node = new TreeNode(height, index);if (root == null) {root = node;} else {insertNode(root, node);}}}// 查詢節點for (int[] op : operations) {int height = op[0];int index = op[1];if (height == Integer.MIN_VALUE) {// 查詢操作TreeNode target = findNode(root, index);if (target == null) {result.add(null);} else {result.add(target.height);}} else {result.add(height);}}// 轉換為數組int[] res = new int[result.size()];for (int i = 0; i < result.size(); i++) {if (result.get(i) == null) {res[i] = Integer.MIN_VALUE; // 用 MIN_VALUE 表示 null} else {res[i] = result.get(i);}}return res;}private void insertNode(TreeNode root, TreeNode node) {TreeNode current = root;while (true) {if (node.height == current.height) {if (current.left == null) {current.left = node;break;} else {current = current.left;}} else if (node.height > current.height) {if (current.right == null) {current.right = node;break;} else {current = current.right;}} else {if (current.left == null) {current.left = node;break;} else {current = current.left;}}}}private TreeNode findNode(TreeNode root, int index) {if (root == null) return null;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {TreeNode node = queue.poll();if (node.index == index) return node;if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}return null;}
}
Python
class TreeNode:def __init__(self, height, index):self.height = heightself.index = indexself.left = Noneself.right = Noneclass Solution:def recoverTree(self, operations):root = Noneresult = []# 構建樹for height, index in operations:if height is not None:node = TreeNode(height, index)if root is None:root = nodeelse:self.insert_node(root, node)# 查詢節點for height, index in operations:if height is None:target = self.find_node(root, index)result.append(target.height if target else None)else:result.append(height)return resultdef insert_node(self, root, node):current = rootwhile True:if node.height == current.height:if current.left is None:current.left = nodebreakelse:current = current.leftelif node.height > current.height:if current.right is None:current.right = nodebreakelse:current = current.rightelse:if current.left is None:current.left = nodebreakelse:current = current.leftdef find_node(self, root, index):if not root:return Nonefrom collections import dequequeue = deque([root])while queue:node = queue.popleft()if node.index == index:return nodeif node.left:queue.append(node.left)if node.right:queue.append(node.right)return None
C++
#include <vector>
#include <queue>
using namespace std;class TreeNode {
public:int height;int index;TreeNode* left;TreeNode* right;TreeNode(int h, int idx) : height(h), index(idx), left(nullptr), right(nullptr) {}
};class Solution {
public:vector<int> recoverTree(vector<vector<int>>& operations) {TreeNode* root = nullptr;vector<int> result;// 構建樹for (const auto& op : operations) {int height = op[0];int index = op[1];if (height != INT_MIN) {TreeNode* node = new TreeNode(height, index);if (!root) {root = node;} else {insertNode(root, node);}}}// 查詢節點for (const auto& op : operations) {int height = op[0];int index = op[1];if (height == INT_MIN) {TreeNode* target = findNode(root, index);if (target) {result.push_back(target->height);} else {result.push_back(INT_MIN);}} else {result.push_back(height);}}return result;}private:void insertNode(TreeNode* root, TreeNode* node) {TreeNode* current = root;while (true) {if (node->height == current->height) {if (!current->left) {current->left = node;break;} else {current = current->left;}} else if (node->height > current->height) {if (!current->right) {current->right = node;break;} else {current = current->right;}} else {if (!current->left) {current->left = node;break;} else {current = current->left;}}}}TreeNode* findNode(TreeNode* root, int index) {if (!root) return nullptr;queue<TreeNode*> q;q.push(root);while (!q.empty()) {TreeNode* node = q.front();q.pop();if (node->index == index) return node;if (node->left) q.push(node->left);if (node->right) q.push(node->right);}return nullptr;}
};
JavaScript
class TreeNode {constructor(height, index) {this.height = height;this.index = index;this.left = null;this.right = null;}
}/*** @param {number[][]} operations* @return {number[]}*/
var recoverTree = function(operations) {let root = null;let result = [];// 構建樹for (let [height, index] of operations) {if (height !== null) {let node = new TreeNode(height, index);if (!root) {root = node;} else {insertNode(root, node);}}}// 查詢節點for (let [height, index] of operations) {if (height === null) {let target = findNode(root, index);result.push(target ? target.height : null);} else {result.push(height);}}return result;function insertNode(root, node) {let current = root;while (true) {if (node.height === current.height) {if (!current.left) {current.left = node;break;} else {current = current.left;}} else if (node.height > current.height) {if (!current.right) {current.right = node;break;} else {current = current.right;}} else {if (!current.left) {current.left = node;break;} else {current = current.left;}}}}function findNode(root, index) {if (!root) return null;let queue = [root];while (queue.length) {let node = queue.shift();if (node.index === index) return node;if (node.left) queue.push(node.left);if (node.right) queue.push(node.right);}return null;}
};

復雜度分析

  • 時間復雜度:O(Q * H),其中 Q 是操作次數,H 是樹的高度。每次插入和查詢都需要遍歷樹的深度,平均情況下為 O(log Q),最壞情況下(樹退化為鏈)為 O(Q)。
  • 空間復雜度:O(Q)。樹中最多有 Q 個節點,存儲樹和隊列的空間為 O(Q)。

測試用例示例

測試用例 1:
輸入: operations = [[0, 0], [0, 1], [1, 1], [1, 0], [0, 0]]
預期輸出: [0, 0, 1, 1, 0]
解釋: 按照操作構建樹,最后查詢高度 0,索引 0 的節點,返回 0。

測試用例 2:
輸入: operations = [[-1, 0], [1, 3], [null, 2]]
預期輸出: [-1, 0, 1, 3, null, 2]
解釋: 構建樹后,查詢索引 2 的節點,未找到,返回 null。

測試用例 3:
輸入: operations = [[0, 0], [1, 1], [null, 1]]
預期輸出: [0, 0, 1, 1]
解釋: 構建樹后,查詢索引 1 的節點,返回高度 1。

問題總結

本題是一個樹結構的構建和查詢問題,核心在于根據高度和索引的規則插入節點,并通過層次遍歷查詢目標節點。算法的關鍵點包括:

  1. 插入規則:高度決定插入方向,相同高度優先左子樹。
  2. 查詢效率:通過層次遍歷查找目標節點。
  3. 邊界處理:處理 null 查詢和未找到節點的情況。

該算法適用于動態構建樹并查詢的場景,但在樹退化為鏈時效率較低。可能的優化方向包括使用平衡樹(如 AVL 樹或紅黑樹)來降低樹高,從而將時間復雜度優化到 O(Q * log Q)。在實際應用中,例如文件系統或組織結構管理,可以用類似方法動態構建和查詢樹結構。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/72582.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/72582.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/72582.shtml

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

相關文章

Vue3 + Element Plus 圖片加載優化全攻略

如果對你有幫助&#xff0c;請幫忙點個贊 一、為什么需要優化圖片加載&#xff1f; 在Web開發中&#xff0c;未優化的圖片會導致&#xff1a; 首屏加載時間過長&#xff08;LCP指標惡化&#xff09; 不必要的帶寬消耗 低端設備卡頓 用戶流量浪費 Element Plus的<el-im…

Python 基礎知識整理筆記

鬧麻了&#xff0c;因為各種原因&#xff0c;現在需要重新回顧一下Python&#xff0c;話不多說&#xff0c;開始吧 1. Python是解釋型語言 && Python與C代碼執行過程的區別&#xff1a; &#xff08;1&#xff09;C 源碼&#xff08;Source&#xff09;&#xff1a;C的…

Windows Server中的NTP服務器部署(NTP Srver Deployment in Windows Server)

構建穩定內網時間同步&#xff1a;Windows Server中的NTP服務器部署指南 服務簡介 NTP&#xff08;Network Time Protocol&#xff09;服務器是用于同步計算機網絡中各設備時間的服務器。它通過網絡協議與標準時間源&#xff08;如原子鐘、GPS系統等&#xff09;進行時間同步&…

Linux驅動開發實戰之PCIE驅動(一)

以下是針對Linux下PCI設備驅動開發的詳細步驟指南及示例代碼&#xff0c;適合剛入門的小白逐步學習和實踐&#xff1a; 一、開發環境準備 安裝開發工具sudo apt install build-essential linux-headers-$(uname -r)創建項目目錄mkdir pci_driver && cd pci_driver二、…

【 <二> 丹方改良:Spring 時代的 JavaWeb】之 Spring Boot 的自動配置:約定優于配置的設計美學

<前文回顧> 點擊此處查看 合集 https://blog.csdn.net/foyodesigner/category_12907601.html?fromshareblogcolumn&sharetypeblogcolumn&sharerId12907601&sharereferPC&sharesourceFoyoDesigner&sharefromfrom_link <今日更新> 一、Spring…

SourceTree的安裝與使用

SourceTree的安裝與使用 一、前言 作為可視化Git管理工具&#xff0c;SourceTree可以避免我們使用命令進行常規的代碼拉取&#xff0c;更新&#xff0c;合并等操作。 鼠標點點就可以完成代碼管理的工作。所以強烈推薦可視化的工具。不過SourceTree還是有點bug&#xff0c;比…

JMeter 性能測試

Jmeter 用戶手冊 名詞解釋&#xff1a; RPS&#xff1a;每秒請求數-每秒向服務器發送多少請求數&#xff08;一個場景&#xff0c;系統面臨多大的壓力&#xff09; TPS&#xff1a;每秒事務數-每秒能夠處理多少請求/事務數性能評價標準&#xff08;其中的一個核心指標&#x…

Go語言的負載均衡

Go語言的負載均衡 引言 在互聯網快速發展的今天&#xff0c;服務器的壓力越來越大。隨著用戶的增加&#xff0c;單一服務器很難滿足所有請求&#xff0c;導致延遲增加&#xff0c;服務質量下降。負載均衡&#xff0c;作為一種重要的技術手段&#xff0c;能夠有效地分散用戶請…

【Mac 從 0 到 1 保姆級配置教程 09】09. 快速配置終端復用工具 tmux 和 oh-my-tmux

文章目錄 1. 前言2. 安裝 tmux3. 配置 tmux4. 安裝 oh-my-tmux5. 最后6. 參考資料7. 系列教程 Mac 從 0 到 1 保姆級配置教程目錄&#xff0c;點擊即可跳轉對應文章&#xff1a; 【Mac 從 0 到 1 保姆級配置教程 00】 - 教程說明 【Mac 從 0 到 1 保姆級配置教程 01】 - 安裝無…

【每日學點HarmonyOS Next知識】屏幕參數、半模態相關、三集聯動、只顯示部分卡面,自定義繪制

1、HarmonyOS 需要 獲取屏幕 xdpi 與 ydpi 數據&#xff1f; 可以通過display.getDefaultDisplaySync參考鏈接&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-display-V5 ohos.display (屏幕屬性) &#xff1a;屏幕屬性提供管理…

Java 大視界 -- 基于 Java 的大數據機器學習模型的遷移學習應用與實踐(129)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

通義萬相 2.1 與藍耘智算平臺的深度協同,挖掘 AIGC 無限潛力并釋放巨大未來價值

我的個人主頁 我的專欄&#xff1a; 人工智能領域、java-數據結構、Javase、C語言&#xff0c;希望能幫助到大家&#xff01;&#xff01;&#xff01; 點贊&#x1f44d;收藏? 引言&#xff1a;AIGC 浪潮下的新機遇 在當今數字化飛速發展的時代&#xff0c;人工智能生成內容&…

【BERT和GPT的區別】

BERT采用完形填空&#xff08;Masked Language Modeling, MLM&#xff09;與GPT采用自回歸生成&#xff08;Autoregressive Generation&#xff09;的差異&#xff0c;本質源于兩者對語言建模的不同哲學導向與技術目標的根本分歧。這種選擇不僅塑造了模型的架構特性&#xff0c…

Java實體類轉JSON時如何避免null值變成“null“?

在Java開發中&#xff0c;實體類與JSON的轉換是一個非常常見的需求。今天&#xff0c;我們要聊聊一個特別的重要但又常常被忽視的問題&#xff1a;當我們將Java實體類轉換為JSON格式時&#xff0c;如何處理那些null值&#xff0c;避免它們在JSON中出現為字符串“null”呢&#…

五大基礎算法——枚舉算法

枚舉算法 是一種通過遍歷所有可能的解來尋找問題答案的算法思想。它通常用于解決那些解空間有限且可以直接列舉所有可能情況的問題。以下是枚舉算法的核心概念、適用場景、實現方法及經典例題&#xff1a; 一、核心概念 解空間 所有可能的解的集合。 遍歷 通過循環或遞歸逐一檢…

C語言高級學習之變量和內存分布

一.變量和內存分布 1.課程要求 2.技術層次 3.C語言標準 1.3.1 K&R C 起初&#xff0c;C語言沒有官方標準。1978年由美國電話電報公司(AT&T&#xff09;貝爾實驗室正式發表了C語言。布萊恩柯林漢&#xff08;Brian Kernighan&#xff09; 和 丹尼斯里奇&#xff08;D…

【004】deepseek本地化部署后,python的調用方式_#py

python調用本地deepseek 1 本地化部署deepseek2 python調用方式 1 本地化部署deepseek 已經有很多大佬們說了不少部署本地化部署deepseek的工作了&#xff0c;我就不過多重復了。 先安裝Ollama軟件&#xff0c;再通過Ollama獲取deepseek的模型文件&#xff0c;大家根據電腦的配…

藍橋杯學習-12遞歸

12遞歸 1.概述 2.幾個遞歸模板 (1)求階乘 int f(int n){ if(n 1) return 1; return f(n-1) * n; }(2)斐波拉契序列 int f(int n){ if(n 1 || n 2) return n; return f(n - 1) f(n - 2); }例題一-藍橋5194 int f(int n){if(n 0) return 1;if(n % 2 0) return f(n / 2)…

Python----數據可視化(Pyecharts三:繪圖二:漣漪散點圖,K線圖,漏斗圖,雷達圖,詞云圖,地圖,柱狀圖折線圖組合,時間線輪廓圖)

1、漣漪特效散點圖 from pyecharts.globals import SymbolType from pyecharts.charts import EffectScatter from pyecharts.faker import Faker from pyecharts import options as opts from pyecharts.globals import ThemeType # 繪制圖表 es (EffectScatter(init_optsop…

自然語言處理預訓練模型的研究綜述

&#x1f4d5;參考&#xff1a;&#xff1a;2020-11-02,https://kns.cnki.net/kcms/detail/11.2127.tp.20201030.1952.017.html 主要是這篇文章的自己摘了點筆記。 預訓練模型的深度學目標是如何使預訓練好的模型處于良好的初始狀態&#xff0c;在下游任務中達到更好的性能表現…