根据中序遍历与前序遍历确定二叉树
对于一棵树而言,前序遍历的形式为:
[根节点,[左子树的前序遍历],[右子树的前序遍历]]。
中序遍历形式为:
[[左子树的中序遍历],根节点,[右子树的中序遍历]]
因此,只要我们定位到根节点在中序遍历中的位置,就可以知道其左边的序列是其左子树的中序遍历,右边的序列是其右子树中序遍历的结果。此外,由于中序与前序遍历,其子树节点的数量是一定的,所以可以进一步确定根节点的左子树与右子树的前序与中序遍历。因此,我们就可以递归的构造左子树与右子树。
代码实现如下:
public class Solution {
Map<Integer,Integer> index=new HashMap<>();
int pre_idx;
int[] preorder;
int[] inorder;
public TreeNode buildTree(int[] preorder, int[] inorder) {
this.preorder=preorder;
this.inorder=inorder;
pre_idx=0;
int n=inorder.length;
for (int i=0;i<inorder.length;i++){
index.put(inorder[i],i);
}
return helper(0,n-1);
}
public TreeNode helper(int in_start, int in_end) {
if (in_end<in_start)
return null;
int root_val=preorder[pre_idx];
int in_root_index=index.get(root_val);
TreeNode root=new TreeNode(root_val);
pre_idx++;
//递归确定左子树
root.left=helper(in_start,in_root_index-1);
//递归确定右子树
root.right=helper(in_root_index+1,in_end);
return root;
}
}
根据中序遍历与后序遍历确定二叉树
与上一个小节类似,对于一棵树而言,前序遍历的形式为:
[[左子树的后序遍历],[右子树的后序遍历],根节点]。
类似的,我们也可以通过后序与中序根节点的位置关系确定二叉树。后序遍历从后向前遍历,则子一个节点必是根节点。其他的思路与上一小节相似。递归实现,代码如下:
public class Solution {
int post_idx;
int[] postorder;
int[] inorder;
Map<Integer,Integer> idx_map=new HashMap<Integer,Integer>();
public TreeNode helper(int in_left,int in_right){
if (in_right<in_left)
return null;
int root_val=postorder[post_idx];
int in_root_index=idx_map.get(root_val);
TreeNode root=new TreeNode(root_val);
post_idx--;
//递归确定右子树
root.right=helper(in_root_index+1,in_right);
//递归确定左子树
root.left=helper(in_left,in_root_index-1);
return root;
}
public TreeNode buildTree(int[] inorder, int[] postorder) {
this.postorder = postorder;
this.inorder = inorder;
// 从后序遍历的最后一个元素开始
post_idx = postorder.length - 1;
// 建立(元素,下标)键值对的哈希表
int idx = 0;
for (Integer val : inorder) {
idx_map.put(val, idx++);
}
return helper(0, inorder.length - 1);
}
}