今天分享的題目來(lái)源于 LeetCode 上的劍指 Offer 系列面試題07. 重建二叉樹(shù),近半年在微軟面試環(huán)節(jié)出現(xiàn)過(guò) 2 次,屬于中高難度的算法題!
一、題目描述
輸入某二叉樹(shù)的前序遍歷和中序遍歷的結(jié)果,請(qǐng)重建該二叉樹(shù)。假設(shè)輸入的前序遍歷和中序遍歷的結(jié)果中都不含重復(fù)的數(shù)字。
例如,給出
前序遍歷preorder=[3,9,20,15,7] 中序遍歷inorder=[9,3,15,20,7]
返回如下的二叉樹(shù):
3 / 920 / 157
限制:
0 <= 節(jié)點(diǎn)個(gè)數(shù) <= 5000
二、題目解析
首先,我們先來(lái)復(fù)習(xí)一下前序遍歷、中序遍歷。(在下方的視頻中分布講解)
前序遍歷
二叉樹(shù)的前序遍歷順序是:根節(jié)點(diǎn)、左子樹(shù)、右子樹(shù),每個(gè)子樹(shù)的遍歷順序同樣滿足前序遍歷順序。
中序遍歷
二叉樹(shù)的中序遍歷順序是:左子樹(shù)、根節(jié)點(diǎn)、右子樹(shù),每個(gè)子樹(shù)的遍歷順序同樣滿足中序遍歷順序。
復(fù)習(xí)過(guò)后,我們可以得出以下結(jié)論:
在二叉樹(shù)的前序遍歷序列中,第一個(gè)數(shù)字總是樹(shù)的根結(jié)點(diǎn)的值;
在二叉樹(shù)的中序遍歷序列中,根結(jié)點(diǎn)的值在序列的中間,左子樹(shù)的結(jié)點(diǎn)的值位于根結(jié)點(diǎn)的值的左邊,而右子樹(shù)的結(jié)點(diǎn)的值位于根結(jié)點(diǎn)的值的右邊

以本題的序列為例,前序遍歷序列的第一個(gè)數(shù)字 3 就是根結(jié)點(diǎn)的值,在中序遍歷序列,找到根結(jié)點(diǎn)值的位置。根據(jù)中序遍歷特點(diǎn),在根結(jié)點(diǎn)的值 3前面的數(shù)字都是左子樹(shù)結(jié)點(diǎn)的值,在根結(jié)點(diǎn)的值 3后面的數(shù)字都是右子樹(shù)結(jié)點(diǎn)的值。
二叉樹(shù)很重要的一個(gè)性質(zhì)是遞歸,在找到了左子樹(shù)、右子樹(shù)的前序遍歷序列和中序遍歷序列后,我們可以按照同樣的方法去確定子左子樹(shù)和子右子樹(shù)的構(gòu)建。
具體的代碼編寫(xiě)思路如下(來(lái)源于 Krahets's Blog):
遞推參數(shù):前序遍歷中根節(jié)點(diǎn)的索引pre_root_idx、中序遍歷左邊界in_left_idx、中序遍歷右邊界in_right_idx。
終止條件:當(dāng)in_left_idx > in_right_idx,子樹(shù)中序遍歷為空,說(shuō)明已經(jīng)越過(guò)葉子節(jié)點(diǎn),此時(shí)返回 null 。
遞推工作:
建立根節(jié)點(diǎn) root :值為前序遍歷中索引為pre_root_idx的節(jié)點(diǎn)值。
搜索根節(jié)點(diǎn) root 在中序遍歷的索引 i :為了提升搜索效率,本題解使用哈希表map預(yù)存儲(chǔ)中序遍歷的值與索引的映射關(guān)系,每次搜索的時(shí)間復(fù)雜度為 O(1)。
構(gòu)建根節(jié)點(diǎn)root的左子樹(shù)和右子樹(shù):通過(guò)調(diào)用 recursive()方法開(kāi)啟下一層遞歸。
左子樹(shù):根節(jié)點(diǎn)索引為 pre_root_idx + 1 ,中序遍歷的左右邊界分別為 in_left_idx 和 i - 1。
右子樹(shù):根節(jié)點(diǎn)索引為 i - in_left_idx + pre_root_idx + 1(即:根節(jié)點(diǎn)索引 + 左子樹(shù)長(zhǎng)度 + 1),中序遍歷的左右邊界分別為 i + 1 和 in_right_idx。
返回值:返回root,含義是當(dāng)前遞歸層級(jí)建立的根節(jié)點(diǎn)root為上一遞歸層級(jí)的根節(jié)點(diǎn)的左或右子節(jié)點(diǎn)。
三、動(dòng)畫(huà)描述
四、圖片描述


















五、參考代碼
classSolution{ //在中序序列中查找與前序序列首結(jié)點(diǎn)相同元素的時(shí)候,如果使用while循環(huán)去一個(gè)個(gè)找效率很慢 //這里我們借助數(shù)據(jù)結(jié)構(gòu)HashMap來(lái)輔助查找,在開(kāi)始遞歸之前把所有的中序序列的元素和它們所在的下標(biāo)存到一個(gè)map中,這樣查找的時(shí)間復(fù)雜度是O(logn) HashMap
這段代碼的一個(gè)難點(diǎn)就是root.left與root.right,我這里抽離出來(lái)詳細(xì)解釋一下。
1、root.left

2、root.right

六、復(fù)雜度分析
時(shí)間復(fù)雜度
時(shí)間復(fù)雜度為 O(N)。
空間復(fù)雜度
空間復(fù)雜度為 O(N)。
七、相關(guān)標(biāo)簽
樹(shù)
遞歸
哈希表
八、參考來(lái)源
1、https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/ 題解區(qū)
2、https://krahets.gitee.io/views/sword-for-offer/2020-02-24-sword-for-offer-07.html
-
數(shù)字
+關(guān)注
關(guān)注
1文章
1700瀏覽量
52557 -
二叉樹(shù)
+關(guān)注
關(guān)注
0文章
74瀏覽量
12939
原文標(biāo)題:面試字節(jié)跳動(dòng)時(shí),我竟然遇到了原題……
文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
TCP三次握手與四次揮手的詳細(xì)過(guò)程
億緯鋰能與杭叉集團(tuán)達(dá)成戰(zhàn)略合作
通過(guò)優(yōu)化代碼來(lái)提高M(jìn)CU運(yùn)行效率
人工智能工程師高頻面試題匯總:循環(huán)神經(jīng)網(wǎng)絡(luò)篇(題目+答案)
用30道電子工程師面試題來(lái)拷問(wèn)墮落的你...
請(qǐng)問(wèn)rtt studio 的文件夾打紅叉什么意思?
億緯鋰能榮獲杭叉集團(tuán)2022-2024年度優(yōu)秀供應(yīng)商獎(jiǎng)
每周推薦!硬件設(shè)計(jì)指南+無(wú)刷電機(jī)原理圖大全+工程師面試題庫(kù)匯總
硬件工程師或研發(fā)類(lèi)筆試面試題庫(kù)匯總
最全的硬件工程師筆試試題集
【硬件方向】名企面試筆試真題:大疆創(chuàng)新校園招聘筆試題
硬件工程師面試/筆試經(jīng)典 100 題
硬件工程師面試必看試題(經(jīng)典)
請(qǐng)問(wèn)有沒(méi)有辦法修改live系統(tǒng)上的設(shè)備樹(shù)?
模電與數(shù)電的基本知識(shí) (學(xué)習(xí)備用)
Offer系列面試題0:重建二叉樹(shù)
評(píng)論