Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
<Solution>You may assume that duplicates do not exist in the tree.
這題要我們從 preorder 和 inorder traversal 兩個資訊中,把 binary tree 給重建出來
這邊先注意到題目有說,不會有重複的元素
因為有這個前題條件,我們可以找出 preorder traversal 中的某個值,在 inorder traversal 中的位置
舉例
1
/ \
2 7
/ \ \
6 9 8
preorder : [1, 2, 6, 9, 7, 8]
inorder : [6, 2, 9, 1, 7, 8]
因為 preorder 的特性,preorder[0] = 1 一定是 root
找出 1 在 inorder 的位置,index = 4,inorder[4] = 1
那麼,inorder[0] 到 inorder[3] 一定是在 inorder[4] 的左子樹
inorder[5] 到 inorder[6] 一定是在 inorder[4] 的右子樹
因此,可以每次都以 preorder 的第一個元素當 root,然後 recursive 的找出左子樹和右子樹
那當找左右子樹的時候,preorder 的範圍變化會如下
找左子樹時:
preorder[0] 會是當下的 root
preorder : [1, 2, 6, 9, 7, 8]
inorder : [6, 2, 9, 1, 7, 8]
preorder 不需要再看 index 0,只看 index 1 到 index 5
將 preorder[1-5] 繼續 recursive 下去
preorder : [2, 6, 9, 7, 8]
inorder : [6, 2, 9, 3, 7, 8]
找右子樹時:
preorder[0] 會是當下的 root
preorder : [1, 2, 6, 9, 7, 8]
inorder : [6, 2, 9, 1, 7, 8]
而這時候,inorder[0-2] 這三個數都是左子樹的元素,且都已經處理完了
所以接下來要看的地方是 inorder[4-5]
這也代表在 preorder 中,從 preorder[0] 往右數 3 個 (inorder[0-2]) 都是處理過的數
所以 preorder 的搜尋範圍起始點就會變成 preorderRootIndex + (inorderRootIndex - inorderStart) + 1 = 0 + (3 - 0) + 1 = 4
也就是從 preorder[4] 開始就會是在右子樹的元素
code 如下(參考資料)
這題還有 iterative 的解法
舉例
1
/ \
2 7
/ \ \
6 9 8
preorder : [1, 2, 6, 9, 7, 8]
inorder : [6, 2, 9, 1, 7, 8]
觀念一樣,preorder[0] = 1 一定是 root,所以 inorder[0-2]一定是 root 的左子樹的node
而 inorder[0] = 6,這一定是最左邊的 node
因此,當目前 preorder 的值不等於 inorder[0] 之前,就是一路向左連接下去
1
/
2
/
6
preorder : [1, 2, 6, 9, 7, 8]
inorder : [6, 2, 9, 1, 7, 8]
當 preorder[2] = 6 = inorder[0] 的時候,代表目前所有的 left child 都已經處理完了
接下來就要回推到第一個有 right child 的 node
因為要回推,所以在過程當中,使用 stack 將之前的 node 都儲存起來
此實,stack 裡面有 [1, 2, 6]
因為 inorder 的特性,如果有 right child 的 node,其 right child 一定會夾在當前 node 和它的 parent 之間
就像是例子中的 9 : inorder : [6, 2, 9, 1, 7, 8]
因此,只要檢查 stack 裡面的 top,是不是和當前 inorder 的值一樣
是的話,就 pop 出來,然後用一個 tmpNode 指到它,並且將 inorder 的 index 指到下一個
所以會變成
1
/
2
/ \
6 9
tmpNode = 2
preorder : [1,
inorder : [6, 2, 9, 1, 7, 8]
這時候把 9 變成 2 的 right child,並且再把 9 丟到 stack 就可以了
stack = [1,9]
然後再重複之前的步驟,直到歷遍完 preorder
code 如下 (參考資料)
沒有留言:
張貼留言