java 重建二叉樹
阿新 • • 發佈:2021-01-17
- 利用先序和中序遍歷結果陣列 pre 和 in,重建二叉樹
- 首先考慮初始情況,即兩個初始陣列 pre,in
pre[0]
作為先序遍歷的第一個節點,也是樹根節點,把 in 劃分為左右子樹兩個區間inleft 和 inright
- 根據 in 中 pre[0] 的
下標
,把 pre 陣列同樣劃分為,左右子樹的前序遍歷的兩個區間preleft 和 preright
- 遞迴重建和劃分,直到 pre 和 in 陣列為長度為 0
- 比如,pre = [
1
2 3 4 5 6 7], in = [3 2 41
6 5 7],pre[0] = 1 為樹根節點 - pre[0] 劃分 in 為
左右子樹的中序遍歷陣列
3 2 4
], inright = [6 5 7
],pre[0] 在 in 的下標為 i = 3 - 找 inleft 和 inright 在 pre 中的
對應區間
:preleft = [2 3 4
],preright = [5, 6, 7
] - 遞迴此過程
java 程式碼
import java.util.Arrays;
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
// pre = [1 2 3 4 5 6 7], in = [3 2 4 1 6 5 7]
if (pre.length == 0 || in.length == 0) return null;
// 每次用 pre[0] 建立樹根節點,第一次為 1
TreeNode root = new TreeNode(pre[0]);
// 查詢 pre[0] 在 in 陣列中的下標,用於後續劃分 pre 和 in 陣列
int i = getRootIndex(in, pre[0]); // i = 3
// 在 in 陣列中,擷取左子樹的中序遍歷陣列 inleft = [3 2 4]
int[] inleft = Arrays.copyOfRange (in, 0, i);
// 在 pre 陣列中,擷取 inleft 對應的先序遍歷陣列 preleft = [2 3 4]
int[] preleft = Arrays.copyOfRange(pre, 1, i + 1); // 除開 pre[0], 下標整體加 1
// 遞迴構建 root 左子樹
root.left = reConstructBinaryTree(preleft, inleft);
// 在 in 陣列中,擷取右子樹的中序遍歷陣列 inright = [6 5 7]
int[] inright = Arrays.copyOfRange(in, i, in.length);
// 在 pre 陣列中,擷取 inright 對應的前序遍歷陣列 preright = [5 6 7]
int[] preright = Arrays.copyOfRange(pre, i + 1, pre.length);
// 遞迴構建 root 右子樹
root.right = reConstructBinaryTree(preright, inright);
// 返回 root 節點
return root;
}
public int getRootIndex(int[] in, int root) {
for (int i = 0; i < in.length; i++) {
if (in[i] == root) return i;
}
return 0;
}
}
- 總結:遞迴的關鍵是,每次都要找出
當前子樹下對應的 pre 和 in