劍指 Offer 07. 重建二叉樹(中等)
阿新 • • 發佈:2021-01-13
劍指 Offer 07. 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如,給出
前序遍歷 preorder =[3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/ \
9 20
/ \
15 7
限制:
0 <= 節點個數 <= 5000
我的Java程式碼:
思路:給的函式介面直接拿來遞迴感覺還需要再新建陣列,比較麻煩,所以用另一個方法來實現遞迴建樹。遞迴方法中通過移動兩對指標分別界定子樹在兩個陣列中的位置。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { return build(preorder,0,preorder.length,inorder,0,inorder.length); } public TreeNode build(int[] preorder, int preorderLow, int preorderHigh, int[] inorder, int inorderLow, int inorderHigh) { if(preorderLow > preorderHigh || inorderLow > inorderHigh || preorderLow == preorder.length) { return null; } int key = preorder[preorderLow]; int k = inorderLow,left; for(int i = inorderLow;i < inorderHigh;i++) { if(key == inorder[i]) { k = i; break; } } left = k - inorderLow; TreeNode t = new TreeNode(key); t.left = build(preorder,preorderLow+1,preorderLow+left,inorder,inorderLow,k); t.right = build(preorder,preorderLow+left+1,preorderHigh,inorder,k+1,inorderHigh); return t; } }
學習別人的程式碼:
作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-by-leetcode-s/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
思路:迭代
可以使用棧儲存遍歷過的節點。初始時令中序遍歷的指標指向第一個元素,遍歷前序遍歷的陣列,如果前序遍歷的元素不等於中序遍歷的指標指向的元素,則前序遍歷的元素為上一個節點的左子節點。如果前序遍歷的元素等於中序遍歷的指標指向的元素,則正向遍歷中序遍歷的元素同時反向遍歷前序遍歷的元素,找到最後一次相等的元素,將前序遍歷的下一個節點作為最後一次相等的元素的右子節點。其中,反向遍歷前序遍歷的元素可通過棧的彈出元素實現。
- 使用前序遍歷的第一個元素建立根節點。
- 建立一個棧,將根節點壓入棧內。
- 初始化中序遍歷下標為 0。
- 遍歷前序遍歷的每個元素,判斷其上一個元素(即棧頂元素)是否等於中序遍歷下標指向的元素。
- 若上一個元素不等於中序遍歷下標指向的元素,則將當前元素作為其上一個元素的左子節點,並將當前元素壓入棧內。
- 若上一個元素等於中序遍歷下標指向的元素,則從棧內彈出一個元素,同時令中序遍歷下標指向下一個元素,之後繼續判斷棧頂元素是否等於中序遍歷下標指向的元素,若相等則重複該操作,直至棧為空或者元素不相等。然後令當前元素為最後一個想等元素的右節點。
- 遍歷結束,返回根節點。
精選第一的題解更好理解迭代方法:詳細通俗的思路分析,多解法
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0) {
return null;
}
TreeNode root = new TreeNode(preorder[0]);
int length = preorder.length;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
int inorderIndex = 0;
for (int i = 1; i < length; i++) {
int preorderVal = preorder[i];
TreeNode node = stack.peek();
if (node.val != inorder[inorderIndex]) {
node.left = new TreeNode(preorderVal);
stack.push(node.left);
} else {
while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {
node = stack.pop();
inorderIndex++;
}
node.right = new TreeNode(preorderVal);
stack.push(node.right);
}
}
return root;
}
}
作者:LeetCode-Solution
連結:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-by-leetcode-s/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。