二叉樹(shù) 15 (從中序與后序遍歷序列構(gòu)造二叉樹(shù) leetcode 106)

思想

二叉樹(shù)的核心思想是分治和遞歸,特點(diǎn)是遍歷方式是钥。
解題方式常見(jiàn)兩類思路:

  1. 遍歷一遍二叉樹(shù)尋找答案掠归;
  2. 通過(guò)分治分解問(wèn)題尋求答案;

遍歷分為前中后序悄泥,本質(zhì)上是遍歷二叉樹(shù)過(guò)程中處理每個(gè)節(jié)點(diǎn)的三個(gè)特殊時(shí)間點(diǎn):

  1. 前序是在剛剛進(jìn)入二叉樹(shù)節(jié)點(diǎn)時(shí)執(zhí)行虏冻;
  2. 后序是在將要離開(kāi)二叉樹(shù)節(jié)點(diǎn)時(shí)執(zhí)行;
  3. 中序是左子樹(shù)遍歷完進(jìn)入右子樹(shù)前執(zhí)行弹囚;
# 前序
     1 node
    /      \
 2 left   3 right
中左右
 
# 中序
     2 node
    /      \
 1 left    3 right
左中右
 
# 后序
     3 node
    /      \
 1 left    2 right     
左右中       

多叉樹(shù)只有前后序列遍歷厨相,因?yàn)橹挥卸鏄?shù)有唯一一次中間節(jié)點(diǎn)的遍歷

題目的關(guān)鍵就是找到遍歷過(guò)程中的位置,插入對(duì)應(yīng)代碼邏輯實(shí)現(xiàn)場(chǎng)景的目的鸥鹉。

實(shí)例

從中序與后序遍歷序列構(gòu)造二叉樹(shù) leetcode 106

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

輸入:
(1)inorder: List[int]蛮穿,中序遍歷整數(shù)數(shù)組
(2)postorder: List[int],后序遍歷整數(shù)數(shù)組

輸出:
TreeNode毁渗,根據(jù)兩個(gè)遍歷數(shù)組構(gòu)建一顆二叉樹(shù)践磅,返回根節(jié)點(diǎn)。

舉例:
給定 inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
返回二叉樹(shù) [3,9,20,null,null,15,7]

    3                 
   / \               
 9    20         
      / \          
     15  7        

二叉樹(shù)的數(shù)據(jù)存儲(chǔ)可以使用鏈表灸异,也可以使用數(shù)組音诈,往往數(shù)組更容易表達(dá),根節(jié)點(diǎn)從 index=1 處開(kāi)始存儲(chǔ)绎狭,浪費(fèi) index=0 的位置
left_child = 2 * parent
right_child = 2 * parent + 1
parent = child // 2

分治解

基本情境是找到當(dāng)前構(gòu)建二叉樹(shù)的根節(jié)點(diǎn)和左右子樹(shù)细溅,要利用中序和后序遍歷的特點(diǎn)。
根節(jié)點(diǎn)很容易獲得儡嘶,就是后序遍歷當(dāng)前范圍的最后一個(gè)元素喇聊,因?yàn)楹笮虮闅v是最后進(jìn)入當(dāng)前節(jié)點(diǎn)的。

# 中序
root.left ... | root.val | root.right ...

# 后序
root.left ... | root.right ... | root.val

通過(guò)后序的根節(jié)點(diǎn)蹦狂,能夠在中序的數(shù)組中找到誓篱,進(jìn)而獲取左子樹(shù)和右子樹(shù)朋贬。
題目中說(shuō)明沒(méi)有重復(fù)元素,因此可以用哈希存儲(chǔ)元素的下標(biāo)提高效率窜骄。

編碼


from typing import Optional, List


class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right


def construct_binary_tree_from_inorder_and_postorder_traversal(inorder: List[int], postorder: List[int]) -> Optional[
    TreeNode]:
    # 記錄中序的元素下標(biāo)
    inorder_dict = {}

    def build(inorder: List[int], instart: int, inend: int, postorder: List[int], poststart: int, postend: int) -> Optional[TreeNode]:
        # base 條件锦募,返回樹(shù)子葉的左右 None 
        if instart > inend:
            return None
        # 獲取 root 和左右子樹(shù)范圍
        root_val = postorder[postend]
        partition_index = inorder_dict[root_val]
        size = partition_index - instart
        # 構(gòu)建樹(shù)
        root = TreeNode(root_val)
        root.left = build(inorder, instart, partition_index - 1, postorder, poststart, poststart + size - 1)
        root.right = build(inorder, partition_index + 1, inend, postorder, poststart + size, postend - 1)
        return root

    # 獲取中序的元素下標(biāo)位置
    for i in range(len(inorder)):
        inorder_dict[inorder[i]] = i
    return build(inorder, 0, len(inorder) - 1, postorder, 0, len(postorder) - 1)

相關(guān)

二叉樹(shù) 0
二叉樹(shù) 1
二叉樹(shù) 2
二叉樹(shù) 3
二叉樹(shù) 4
二叉樹(shù) 5
二叉樹(shù) 6
二叉樹(shù) 7
二叉樹(shù) 8
二叉樹(shù) 9
二叉樹(shù) 10
二叉樹(shù) 11
二叉樹(shù) 12
二叉樹(shù) 13
二叉樹(shù) 14

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市邻遏,隨后出現(xiàn)的幾起案子糠亩,更是在濱河造成了極大的恐慌,老刑警劉巖准验,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赎线,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡糊饱,警方通過(guò)查閱死者的電腦和手機(jī)垂寥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)另锋,“玉大人滞项,你說(shuō)我怎么就攤上這事∝财海” “怎么了文判?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)台舱。 經(jīng)常有香客問(wèn)我律杠,道長(zhǎng)潭流,這世上最難降的妖魔是什么竞惋? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮灰嫉,結(jié)果婚禮上拆宛,老公的妹妹穿的比我還像新娘。我一直安慰自己讼撒,他們只是感情好浑厚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著根盒,像睡著了一般钳幅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上炎滞,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天敢艰,我揣著相機(jī)與錄音,去河邊找鬼册赛。 笑死钠导,一個(gè)胖子當(dāng)著我的面吹牛震嫉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播牡属,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼票堵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了逮栅?” 一聲冷哼從身側(cè)響起悴势,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎证芭,沒(méi)想到半個(gè)月后瞳浦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡废士,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年叫潦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片官硝。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡矗蕊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出氢架,到底是詐尸還是另有隱情傻咖,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布岖研,位于F島的核電站卿操,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏孙援。R本人自食惡果不足惜害淤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望拓售。 院中可真熱鬧窥摄,春花似錦、人聲如沸础淤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鸽凶。三九已至币砂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間玻侥,已是汗流浹背决摧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蜜徽。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓祝懂,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拘鞋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砚蓬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容