LeetCode(105):重建二叉樹
阿新 • • 發佈:2020-11-18
題目描述
解題思路:遞迴
前序遍歷:根節點->左子節點->右子節點
中序遍歷:左子節點->根節點->右子節點
針對前序和中序遍歷的特點,我們不難得出以下思路
在每一輪遞迴中:
1、用preorder的頭部值 初始化當前的root節點
2、在傳入的2個數組的基礎上,劃分出當前root的左子樹的前序/中序遍歷陣列、以及右子樹的前序/中序遍歷陣列
3、呼叫自身,將左子樹和右子樹掛載到當前root上
4、返回當前root
下面我們具體來看第2個步驟如何實現
我們可以利用js提供的 indexOf 陣列方法,找出當前root在inorder陣列中的位置(記為 rootIndex)
因此,在inorder陣列中,左子樹和右子樹的inorder陣列分別位於 rootIndex 的左邊和右邊
這樣一來,我們就可以利用 js 提供的 slice 方法,在原陣列的基礎上進行切割,從而得到左右子樹的前序/中序遍歷陣列
除此之外,我們還要考慮一些特殊的情況:
- 傳入的前序/中序遍歷陣列為空:返回空
- 傳入的前序/中序遍歷陣列長度為1:當前為葉子節點
- rootIndex 等於 0 :當前root節點沒有左子樹
- rootIndex + 1 等於 陣列的長度 :當前 root節點沒有右子樹
程式碼實現(Javascript)
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */ /** * @param {number[]} preorder * @param {number[]} inorder * @return {TreeNode} */ var buildTree = function(preorder, inorder) { if(preorder.length===0 || inorder.length===0){ return null } if(preorder.length === 1 && inorder.length === 1){//沒有左右子樹 return new TreeNode(preorder[0]) } var root=new TreeNode(preorder[0]) let rootIndex=inorder.indexOf(root.val) if(rootIndex!==0){ // 有左子樹 var leftinorder=inorder.slice(0,rootIndex) if(rootIndex + 1 >= preorder.length){//有左子樹,沒有右子樹 var leftpreorder=preorder.slice(1) root.left = buildTree(leftpreorder, leftinorder) root.right= buildTree([],[]) }else{ // 有左右子樹 var leftpreorder=preorder.slice(1,rootIndex+1) var rightinorder=inorder.slice(rootIndex+1) var rightpreorder=preorder.slice(rootIndex+1) root.left = buildTree(leftpreorder, leftinorder) root.right = buildTree(rightpreorder, rightinorder) } }else{ // 沒有左子樹 var rightinorder=inorder.slice(rootIndex+1) var rightpreorder=preorder.slice(rootIndex+1) root.left = buildTree([],[]) root.right = buildTree(rightpreorder, rightinorder) } return root };