LeetCode-劍指offer-07-重建二叉樹
阿新 • • 發佈:2021-02-11
目錄
題目要求
原題連結:劍指 Offer 07. 重建二叉樹 | 105. 從前序與中序遍歷序列構造二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
例如,給出
前序遍歷 preorder = [3,9,20,15,7]
中序遍歷 inorder = [9,3,15,20,7]
返回如下的二叉樹:
3
/ \
9 20
/ \
15 7
限制:
0 <= 節點個數 <= 5000
解題過程
詳情見本人的lc題解
遞迴 | 時間複雜度: O ( n ) O(n) O(n) | 空間複雜度: O ( n ) O(n) O(n) | 推薦
時間複雜度:HashMap的遍歷儲存需要 O ( n ) O(n) O(n),遞迴共建立了n個節點,每次遞迴佔用 O ( 1 ) O(1) O(1)的節點建立開銷損耗
空間複雜度:HashMap佔 O ( n ) O(n) O(n),最差情況,樹退化為連結串列,佔用 O ( n ) O(n) O(n)的深度,最好的情況為滿二叉樹,深度為 o ( l o g n ) o(logn) o(logn)
class Solution {
int [] preorder;
HashMap<Integer, Integer> map = new HashMap<>();
// 前序遍歷 preorder: 根 -- 左 -- 右 第一個肯定是根節點
// 中序遍歷 inorder: 左 -- 根 -- 右
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder = preorder;
for(int i = 0; i < inorder.length; i++){
map.put(inorder[i], i);
}
return rebuild(0, 0, inorder.length - 1);
}
// pre_root_index : 根節點 在 前序遍歷中的下標
// in_left_index: 該節點在中序遍歷中的左邊界
// in_right_index: 該節點在中序遍歷中的右邊界
public TreeNode rebuild(int pre_root_index, int in_left_index, int in_right_index){
if(in_left_index > in_right_index) return null;
// 根節點在中序遍歷中的位置:in_root_index
int in_root_index = map.get(preorder[pre_root_index]);
// 建立一個根節點
TreeNode node = new TreeNode(preorder[pre_root_index]);
// 尋找node的左節點:
// 在前序遍歷中的位置就是 根節點的下標 + 1(右邊一個單位)
// 在中序遍歷中的位置就是: 1. 左邊界不變(因為無法確定),2. 右邊界就是根節點的左邊一個單位 in_root_index - 1
node.left = rebuild(pre_root_index + 1, in_left_index, in_root_index - 1);
// 尋找node的右節點:
// 在前序遍歷中的位置就是 根節點的下標 + 左子樹長度 + 1
// 在中序遍歷中的位置就是: 1. 左邊界在根節點的右邊一個單位 in_root_index + 1, 2. 右邊界無法確定
node.right = rebuild(pre_root_index + in_root_index - in_left_index + 1, in_root_index + 1, in_right_index);
return node;
}
}