ps 重新開啓每日刷題了
題目描述:
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
題目分析:
這其實是一個我們非常熟悉的二叉樹問題,根據先中,或後中重建二叉樹。手寫時它的思路是這樣的:先序判根中序判左右。(這裏就不會手寫的了,畢竟它在數據結構中也是蠻簡單的題型)
舉例:題目中先看先序,1肯定是它的根節點、接下來找左右。看中序中1的位置,1左邊即左節點元素、右邊即右節點元素。那麼接下來肯定是得找根節點1的左子樹根節點,還是先看先序,即2是左子樹根節點。那麼這個左子樹的左右子樹呢?還是看中序,2的左有4、7,右沒有了。即節點2僅有右子樹,然後繼續這樣找下去。。。
思路很容易看出來,還是遞歸。(好像一般樹的操作基本都是遞歸)
我們主要的操作就是不斷的找出子樹的先序和中序隊列。
代碼實現
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function reConstructBinaryTree(pre, vin) {
if (pre.length == 0 || vin.length == 0) {
return null;
};
if (pre.length != vin.length) {
return null;
}
//先序判根中序判左右
let index = vin.indexOf(pre[0]);
let left = vin.slice(0, index); //中序左子樹
let right = vin.slice(index + 1); //中序右子樹
let preLeft = pre.slice(1, index + 1); //先序左子樹
let preRight = pre.slice(index + 1); //先序右子樹
return {
val: pre[0],
//左邊找
left: reConstructBinaryTree(preLeft, left),
//右邊找
right: reConstructBinaryTree(preRight, right)
};
}