/*
* 輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。
* 假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。
* 例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
* 思路:所謂的重建二叉樹,無非就是找到該二叉樹的根節點和左右節點
*/
public class ReConstructBinaryTree {
/*法一:畫圖。1.拿到根節點在中序遍歷結果中的位置,該位置左邊是左子樹,右邊是右子樹
* 2.拿到左子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到左子樹的根節點,即總的根節點的左節點
* 3.拿到右子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到右子樹的根節點,即總的根節點的右節點
*/
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length <= 0)
return null;
TreeNode root = new TreeNode(pre[0]);
if(pre.length == 1)
return root;
//拿到根節點在中序遍歷結果中的位置
int rootIndex = 0;
for(int i = 0;i < in.length;i ++) {
if(in[i] == root.val) {
rootIndex = i;
break;
}
}
//拿到左子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到左子樹的根節點,即總的根節點的左節點
if(rootIndex > 0) { //存在左子樹
int[] prel = new int[rootIndex];
int[] inl = new int[rootIndex];
for(int i = 0;i < rootIndex;i ++) {
prel[i] = pre[i + 1];
inl[i] = in[i];
}
root.left = reConstructBinaryTree(prel, inl);
}
else {
root.left = null;
}
//拿到右子樹的前序遍歷,中序遍歷結果。根據這兩個結果遞歸可以得到右子樹的根節點,即總的根節點的右節點
if(rootIndex < in.length - 1) { //存在右子樹
int[] prer = new int[in.length - 1 - rootIndex];
int[] inr = new int[in.length - 1 - rootIndex];
for(int i = 0;i < in.length - 1 - rootIndex;i ++) {
prer[i] = pre[i + rootIndex + 1];
inr[i] = in[i + rootIndex + 1];
}
root.right = reConstructBinaryTree(prer, inr);
}
else {
root.right = null;
}
return root;
}
//法二:需要畫圖計算起點和終點
public TreeNode reConstructBinaryTree2(int [] pre,int [] in) {
if(pre.length <= 0)
return null;
return reConstruct(pre, 0, pre.length - 1, in, 0, in.length - 1);
}
public TreeNode reConstruct(int [] pre, int preStart, int preEnd, int [] in, int inStart, int inEnd) {
if(preStart >= preEnd || inStart >= inEnd) {
return null;
}
TreeNode root = new TreeNode(pre[preStart]);
for(int i = 0;i < in.length;i ++) {
if(root.val == in[i]) { //找到根節點在中序遍歷結果中的位置
root.left = reConstruct(pre, preStart + 1, preStart + i - inStart, in, inStart, i - 1);
root.right = reConstruct(pre, preStart + i - inStart + 1, preEnd, in, i + 1, inEnd);
}
}
return root;
}
public static void main(String[] args) {
int [] pre = {1,2,4,5,3,6,7};
int [] in = {4,2,5,1,6,3,7};
TreeNode root = new ReConstructBinaryTree().reConstructBinaryTree2(pre, in);
System.out.println(root.val + " " + root.left.val + " " + root.right.val);
}
}
《劍指offer》-重建二叉樹
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.