思路分析參考了:https://www.cnblogs.com/codingmengmeng/p/5856980.html
代碼實現參考了: https://blog.csdn.net/qq_28081081/article/details/80740057
感謝兩位博主
問題描述
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
思路分析:
在二叉樹的前序遍歷中,第一個數字總是樹的根結點的值。而在中序遍歷中,樹的根結點的值在序列的中間,左子樹在跟結點的左邊,右字樹在根結點的右邊。所以,我問需要遍歷中序序列才能找到根結點在中序序列中的位置。
如圖所示,在前序序列的第一個數字就是根結點的值。遍歷中序序列,找到根結點的位置,根結點左邊部分就是根結點的左子樹;根結點的右邊部分就是根結點的右子樹。同樣可以在前序序列中找到左子樹的範圍和右子樹的範圍。
這樣,我們在前序序列和中序序列,分別找了左右子樹對應的子序列。既然我們分別找到了左右子樹的前序和中序序列,我們就可以用同樣的方法去遞歸構建二叉樹
接下來就是實現的代碼:
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root = reBulidTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
public TreeNode reBulidTree(int[] pre,int start,int pend,int[] in,int istart,int iend){
if(start > pend || istart > iend){
return null;
}
//構造根結點
TreeNode p = new TreeNode(pre[start]);
for(int i = istart; i <= iend; i++){
if(pre[start] == in[i]){
//左子樹在前序序列的開始位置start+1,結束位置start+i-istart
//左子樹在中序序列的開始位置istart,結束位置i-1
p.left = reBulidTree(pre,start+1,start+i-istart,in,istart,i-1);
//右子樹在前序序列的開始位置start+i-istart+1,結束位置pend
//右子樹在中序序列的開始位置i+1,結束位置iend
p.right = reBulidTree(pre,start+i+1-istart,pend,in,i+1,iend);
break;
}
}
return p;
}