【面試經典150 | 二叉樹】從中序與后序遍歷序列構造二叉樹

文章目錄

  • 寫在前面
  • Tag
  • 題目來源
  • 題目解讀
  • 解題思路
    • 方法一:遞歸
  • 寫在最后

寫在前面

本專欄專注于分析與講解【面試經典150】算法,兩到三天更新一篇文章,歡迎催更……

專欄內容以分析題目為主,并附帶一些對于本題涉及到的數據結構等內容進行回顧與總結,文章結構大致如下,部分內容會有增刪:

  • Tag:介紹本題牽涉到的知識點、數據結構;
  • 題目來源:貼上題目的鏈接,方便大家查找題目并完成練習;
  • 題目解讀:復述題目(確保自己真的理解題目意思),并強調一些題目重點信息;
  • 解題思路:介紹一些解題思路,每種解題思路包括思路講解、實現代碼以及復雜度分析;
  • 知識回憶:針對今天介紹的題目中的重點內容、數據結構進行回顧總結。

Tag

【遞歸】【二叉樹】


題目來源

106. 從中序與后序遍歷序列構造二叉樹


題目解讀

給你一棵二叉樹的中序和后續遍歷得到的兩個數組,現在根據兩個數組來構造二叉樹。


解題思路

方法一:遞歸

前言

首先回憶一下二叉樹的中序和后續遍歷過程。

二叉樹的中序遍歷過程:

  • 先遞歸遍歷左子樹;
  • 接著遍歷根節點;
  • 最后遞歸遍歷右子樹。

二叉樹的后續遍歷過程:

  • 先遞歸遍歷左子樹;
  • 接著遞歸遍歷右子樹;
  • 最后遍歷根節點。

在「遞歸」遍歷子樹的過程中,我們也是將子樹看成是一棵全新的樹,按照相應的順序進行遍歷。

思路

根據后續遍歷的順序可知,后續遍歷數組的最后一個元素為根節點。

于是可以根據后續遍歷數組中的根節點定位到中序遍歷中的根節點,接著可以將前序遍歷數組分為左子樹、根、右子樹三部分,針對左子樹和右子樹這兩個部分可以利用遞歸來完成二叉樹的構造。

算法

我們需要查找后續遍歷中的元素在中序遍歷中的位置,為了高效查找,利用一個哈希表 idx_map 來記錄中序遍歷中元素的位置。

接著定義遞歸函數 helper(in_left, in_right) 表示在中序遍歷的當前范圍內(中序遍歷的 [in_left, in_right])遞歸構造二叉樹,遞歸入口為 helper(0, n - 1)

  • 遞歸出口:如果 in_left > in_right,說明子樹為空,返回空節點;
  • 選擇后續遍歷的最后一個節點作為根節點;
  • 在哈希表 idx_map 中查詢根節點在中序遍歷中的 idx。從 in_leftidx - 1 數屬于左子樹,從 idx + 1in_right 屬于右子樹;
  • 根據后續遍歷邏輯,遞歸創建右子樹 helper(idx + 1, in_right) 和左子樹 helper(in_left, idx - 1)
  • 最后返回根節點 root

注意:在遞歸創建子樹的時候,先創建右子樹,再創建左子樹。因為在后續遍歷中是先存儲左子樹的節點,再存儲右子樹的節點,最后存儲根節點,如果每次選擇「后續遍歷的最后一個節點」為根節點,則先被構造出來的應該為右子樹。

/*** Definition for a binary tree node.* struct TreeNode {*     int val;*     TreeNode *left;*     TreeNode *right;*     TreeNode() : val(0), left(nullptr), right(nullptr) {}*     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
private:int root_idx;unordered_map<int, int> idx_map;
public:TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {root_idx = postorder.size() - 1;// 建立哈希表int idx = 0;for (auto val : inorder) {idx_map[val] = idx++;}function<TreeNode*(int, int)> helper = [&](int in_left, int in_right) -> TreeNode* {if (in_left > in_right) {return nullptr;}// 選擇 后續遍歷數組的最后一個元素作為當前子樹的根節點int root_val = postorder[root_idx--];TreeNode* root = new TreeNode(root_val);// 根據 root_val 所在位置分為左右兩棵子樹int idx = idx_map[root_val];// 遞歸構建右子樹 root->right = helper(idx + 1, in_right);// 遞歸構建左子樹root->left = helper(in_left, idx - 1);return root;};return helper(0, inorder.size() - 1);}
};

復雜度分析

時間復雜度: O ( n ) O(n) O(n) n n n 為數中節點個數。

空間復雜度: O ( n ) O(n) O(n)


寫在最后

如果您發現文章有任何錯誤或者對文章有任何疑問,歡迎私信博主或者在評論區指出 💬💬💬。

如果大家有更優的時間、空間復雜度的方法,歡迎評論區交流。

最后,感謝您的閱讀,如果有所收獲的話可以給我點一個 👍 哦。

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

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

相關文章

Android : Room 數據庫的基本用法 —簡單應用

1.Room介紹&#xff1a; Android Room 是 Android 官方提供的一個持久性庫&#xff0c;用于在 Android 應用程序中管理數據庫。它提供了一個簡單的 API 層&#xff0c;使得使用 SQLite 數據庫變得更加容易和方便。 以下是 Android Room 的主要特點&#xff1a; 對象關系映射…

9.MySQL 索引

目錄 ???????概述 概念&#xff1a; 單列索引 普通索引 創建索引 查看索引 刪除索引 唯一索引 創建唯一索引 刪除唯一索引 主鍵索引 組合索引 創建索引 全文索引 概述 使用全文索引 空間索引 內部原理 相關算法&#xff1a; hash算法 二叉樹算法 …

Spring基于XML文件配置AOP

AOP AOP&#xff0c;面向切面編程&#xff0c;是對面向對象編程OOP的升華。OOP是縱向對一個事物的抽象&#xff0c;一個對象包括靜態的屬性信息&#xff0c;包括動態的方法信息等。而AOP是橫向的對不同事物的抽象&#xff0c;屬性與屬性、方法與方法、對象與對象都可以組成一個…

12.10多種編碼方式,編碼方案選擇策略(遞歸級聯),PDE,RLE代碼

作者如何選擇和設計編碼方案&#xff0c;以實現高效的解壓縮和高壓縮比&#xff1f;BtrBlocks是否適用于所有類型的數據&#xff1f; 選擇和設計編碼方案&#xff1a; 結合多種高效編碼方案&#xff1a;BtrBlocks 通過選擇一組針對不同數據分布的高效編碼方案&#xff0c;實現…

js判斷是否對象自身為空

文章目錄 一、前言二、JSON.stringify三、for in 配合 hasOwnProperty四、Object.keys五、Object.getOwnPropertyNames六、Object.getOwnPropertyNames 結合 Object.getOwnPropertySymbols七、Reflect.ownKeys八、最后 一、前言 如何判斷一個對象為空&#xff1f; 先上結論&a…

MySql復習筆記03(小滴課堂) 事務,視圖,觸發器,存儲過程

mysql 必備核心知識之事務的詳細解析&#xff1a; 創建一個數據庫表&#xff1a; 添加數據并開啟事務。 添加數據并查詢。 登錄另一臺服務器發現查不到這個表中的數據。 這是因為事務開啟了&#xff0c;但是沒有提交&#xff0c;只是把數據存到了內存中&#xff0c;還沒有寫入…

以為回調函數是同步的(js的問題)

回調函數可以用來處理 JavaScript 的異步操作&#xff0c;但是選用 Promise、async/await 更好&#xff0c;因為多重回調函數會導致回調地獄。 回調函數不是**同步的**&#xff0c;它是延時操作執行完畢后會被調用的一個函數。 比如全局方法 "setTimeout" &#xf…

CString 的 Replace 函數

Replace 使用測試 CString mSectNameNew L"槽a*b*c*d";CString mSectNameNew2 L"Ca*b*c*d";CString mSectNameNew3 L"[a*b*c*d";mSectNameNew.Replace(_T("M"), _T("C")); // 不會替換mSectNameNew.Re…

JOSEF 沖擊繼電器 ZC-23A DC48V 柜內安裝,板前帶座

系列型號 ZC-23沖擊繼電器&#xff1b;ZC-23A沖擊繼電器&#xff1b; ZC-23B沖擊繼電器 一、用途 沖擊繼電器ZC-23A DC48V 柜內安裝板前帶座 (以下簡稱繼電器)&#xff0c;廣泛用于直流操作的繼電器保護及自動控制回路中&#xff0c;作為集中控制信號元件。 二、主要技術參…

C#動態調用C++DLL中的函數

DLL中導出的函數 typedef void (*HQ_MSG_CALLBACK)(void *h, int nMsg, int nMsgType, int nReqNo, const char *szData, int nSize); void SetMsgFunc(void *h, HQ_MSG_CALLBACK pmsgCallBack);C#動態調用上述函數 public delegate void CALLBACK(IntPtr h, int nMsg, int n…

信息處理技術員

目錄 信息處理技術員工作內容 信息處理技術員崗位面試試題舉例 信息處理技術員考試 信息處理技術員工作內容 信息處理技術員是負責處理和管理信息系統的專業人員。他們的主要工作內容包括以下幾個方面&#xff1a; 1.系統維護和管理&#xff1a;信息處理技術員負責維護和管…

大數據股票簡單分析

目錄標題 內容說明解題量化金融的含義量化交易策略 點擊直接資料領取 內容 1解釋量化金融的含義&#xff0c;調研并給出至少 5種量化交易的策略或方法 2.完成Tushare Pro 的安裝、注冊&#xff0c;獲取自己的 Token&#xff0c;查閱網站內的接口講解和示例; 3通過Python 編程完…

力扣刷題總結 字符串(2)【KMP】

&#x1f525;博客主頁&#xff1a; A_SHOWY&#x1f3a5;系列專欄&#xff1a;力扣刷題總結錄 數據結構 云計算 數字圖像處理 28.找出字符串中第一個匹配項的下標mid經典KMP4593重復的子字符串mid可以使用滑動窗口或者KMP KMP章節難度較大&#xff0c;需要深入理解其中…

Flink 本地單機/Standalone集群/YARN模式集群搭建

準備工作 本文簡述Flink在Linux中安裝步驟&#xff0c;和示例程序的運行。需要安裝JDK1.8及以上版本。 下載地址&#xff1a;下載Flink的二進制包 點進去后&#xff0c;選擇如下鏈接&#xff1a; 解壓flink-1.10.1-bin-scala_2.12.tgz&#xff0c;我這里解壓到soft目錄 [ro…

OrangePi ZERO2 刷機與啟動

鏡像準備 用讀卡器和Win32Diskimager刷寫鏡像到內存卡&#xff0c;鏡像文件見下面百度云鏈接&#xff1a;https://pan.baidu.com/s/14aKTznc4Jvw4SoFF54JUTg 提取碼&#xff1a;1815 刷寫完畢后插回香橙派 串口登錄 用MobaXterm和USB-TTL進行串口登錄&#xff0c;MobaXterm軟…

談一談網絡協議中的應用層

文章目錄 一&#xff0c;什么是HTTPHTTP的優缺點HTTPS 一&#xff0c;什么是HTTP 我們在通過網絡進行傳輸數據時&#xff0c;我們要保證&#xff0c;我們在發送時構造的數據&#xff0c;在接收時也能夠解析出來&#xff0c;這本質上就是一種協議&#xff0c;是一種應用層協議&…

Spring Cloud + Vue前后端分離-第3章 SpringBoot項目技術整合

Spring Cloud Vue前后端分離-第3章 SpringBoot項目技術整合 3-1 集成持久層框架Mybatis ORM:對象關系映射&#xff0c;Hibernate是全自動ORM&#xff0c;Mybatis是半自動ORM&#xff0c;Mybatis可以操作的花樣更多&#xff0c;是首選的持久層框架 System模塊集成Mybatis框架…

整數分析 C語言xdoj43

問題描述 給出一個整數n&#xff08;0<n<100000000&#xff09;。求出該整數的位數&#xff0c;以及組成該整數的所有數字中的最大數字和最小數字。 輸入說明 輸入一個整數n&#xff08;0<n<100000000&#xff09; 輸出說明 在一行上依次輸出整數n的位…

Linux內核上游提交完整流程及示例

參考博客文章&#xff1a; 向linux內核提交代碼 - 知乎 一、下載Linux內核源碼 通過git下載Linux內核源碼&#xff0c;具體命令如下&#xff1a; git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 實際命令及結果如下&#xff1a; penghaoDin…

IBM Qiskit量子機器學習速成(六)

量子卷積神經網絡 卷積和池化&#xff1a;卷積神經網絡的必備成分 卷積神經網絡被廣泛應用于圖像和音頻的識別當中&#xff0c;關鍵在于“卷積”操作賦予神經網絡統籌學習數據的能力。 執行卷積操作需要輸入數據與卷積核&#xff0c;卷積核首先與輸入數據左上角對齊&#xf…