輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。
假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
示例:例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。
二叉樹的前序遍歷序列中,第乙個數字總是樹的根節點的值。
二叉樹的中序遍歷序列中,根節點的值在序列的中間,左子樹節點的值位於根節點值的左邊,右子樹節點的值位於根節點值的右邊。
如示例,前序遍歷序列,中序遍歷序列
前序遍歷序列
中序遍歷序列
前序 |
根節點掃瞄中序遍歷序列,找到根節點的位置
中序 |
根節點為左子樹節點的值 共3個節點
為右子樹節點的值 共4個節點
因此前序遍歷中根節點後面的3個數字是3個左子樹節點的值,在後面的數字是右子樹節點的值。
這樣我們找到了左、右子樹的前序遍歷和中序遍歷序列,可以遞迴的構建左子樹和右子樹。
流程大致如下:
(1) 前序遍歷的第乙個數字是根節點的值。
(2) 掃瞄中序遍歷,根據(1)中根節點的值,找到根節點的位置。
(3) 中序遍歷中,根節點值的左邊是左子樹節點的值,右邊是右子樹節點的值。分別確定左右子樹節點數。
(4) 根據(3)中左右子樹節點數,在前序遍歷中找到左右子樹對應的子串行。
(5) 現在已經確定了左右子樹對應的前序和中序遍歷序列,遞迴重建左右子樹。
class solution
treenode* reconstruct(vectorpre, vectorvin, int ps, int pe, int is, int ie)
}node->left = reconstruct(pre, vin, ps + 1, ps + 1 + (pos - 1 - is), is, pos - 1);//重建根節點的左子樹
node->right = reconstruct(pre, vin, pe - (ie - pos - 1), pe, pos + 1, ie);//重建根節點的右子樹
return node;
}};
tips:
node->left = reconstruct(pre, vin, ps + 1, ps + 1 + (pos - 1 - is), is, pos - 1);//重建根節點的左子樹
在上面的語句中,左子樹的中序遍歷序列 在vin中很容易確定是vin[is, pos - 1]
但前序遍歷序列的起點是ps + 1, 終點不容易直接寫出(設為x)
可以考慮相對位置:
x - (ps + 1) = pos - 1 - is
x = ps + 1 + (pos - 1 - is)
同理:node->right = reconstruct(pre, vin, pe - (ie - pos - 1), pe, pos + 1, ie);//重建根節點的右子樹
右子樹的中序遍歷序列 在vin中很容易確定是vin[pos + 1, ie]
但前序遍歷序列的終點是pe, 起點不容易直接寫出(設為y)
可以考慮相對位置:
pe - y = ie - (pos + 1)
y = pe - (ie - pos - 1)
劍指offer面試題7 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹並返回。class solution struct treenode reconstruct int l1,int r1,int l2 pr...
劍指Offer 面試題7 重建二叉樹
題目 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹,假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如,輸入前序遍歷序列和中序遍歷,則重建如圖2.6所示的二叉樹並輸出它的頭節點。分析 前序遍歷 先根,再左,後右 中序遍歷 先左,再根,後右。那麼前序遍歷的第乙個是根,在中序遍歷中找到...
劍指offer 面試題7 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷結果中都不含重複的數字。例如輸入前序遍歷序列和中序遍歷序列,則重建出二叉樹並輸出他的根節點。二叉樹的定義如下 public static class binarytreenode 在二叉樹的前序遍歷中,第乙個數字總...