題目一
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
思路:
1)將中序數組放入hashmap中,第一個存放值,第二個存放座標‘
2)遞歸生成樹,判斷退出條件:前序數組的最左座標大於最右座標。
3) 定位左右子樹的前序和中序數組起始座標。
前序: int[] pre,int pl,int pr,
中序: int[] in,int il,int ir, index是根節點(每次遞歸需要創建的節點)在中序數組中對應的位置,在hashmap中存放。
子樹 | 前序 | 中序 |
左子樹 | pre,pl+1,pl+index-i1 | in,il,index-1 |
右子樹 | pre,pl+index-i1+1,pr | in,index+1,ir |
public static HashMap<Integer,Integer> hs=new HashMap<>();
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
if(pre.length==0||in.length==0) return null;
for(int i=0;i<in.length;i++) hs.put(in[i],i);
return dfs(pre,0,pre.length-1,in,0,in.length-1);
}
public static TreeNode dfs(int[] pre,int pl,int pr,int[] in,int il,int ir){
if(pl>pr) return null;
TreeNode root=new TreeNode(pre[pl]);
int k=hs.get(root.val);
root.left=dfs(pre,pl+1,pl+k-il,in,il,k-1);
root.right=dfs(pre,pl+k-il+1,pr,in,k+1,ir);
return root;
}
題目二
輸入某二叉樹的後序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的後序遍歷和中序遍歷的結果中都不含重複的數字。
思路:類似題目一,
1)將中序數組放入hashmap中,第一個存放值,第二個存放座標‘
2)遞歸生成樹,判斷退出條件:後序數組的最左座標大於最右座標。
3) 定位左右子樹的後序和中序數組起始座標。
後序: int[] pos,int pl,int pr,
中序: int[] in,int nl,int nr, index是根節點(每次遞歸需要創建的節點)在中序數組中對應的位置,在hashmap中存放。
子樹 | 後序 | 中序 |
左子樹 | pos,pl,pl+index-nl-1 | in,nl,index-1 |
右子樹 | pre,pl+index-nl,pr-1 | in,index+1,nr |
public Node inPosToTree(int[] in,int[] pos){
if(in==null||pos==null) return null;
HashMap<Integer,Integer> hs=new HashMap<>();
for(int i=0;i<in.length;i++) hs.put(in[i],i);
return inPos(in,0,in.length-1,pos,0,pos.length-1,hs);
}
public Node inPos(int in,int nl,int nr,int[] pos,int pl,int pr,HashMap<Integer,Integer> map){
if(pl>pr) return null;
Node head=new Node(s[pl]);
int index=map.get(s[pr]);
head.left=inPos(in,nl,index-1,pos,pl,pl+index-nl-1,map);
head.right=inPos(in,index+1,nr,pos,pl+index-nl,pr-1,map);
return head;
}
總結:
難點:定位節點的左右子樹對應的中序和前序、後序中的位置。
1)退出遞歸的判斷條件,前序的最左座標大於最右座標,後序的最左座標大於最右座標;
2)中序的容易定位,根節點所在座標index,左子樹取值範圍[nl,index-1] 右子樹的取值範圍[index+1,nr]
3) 前序,左子樹取值範圍[pl+1,pl+index-nl] 右子樹的取值範圍[pl+index-nl+1,pr]
後序,左子樹取值範圍[posl,posl+index-nl-1] 右子樹的取值範圍[posl+index-nl,posr-1]