中序+后序构造二叉树
题目
思路
在拿到题目的时候,我们应该先分析中序和后序遍历的特点,由于中序:左中右,后序:左右中,我们可以知道以下两点
1. 后序的最后一个结点是根节点
2. 中序知道了根节点,那么左右两边就是左右子树
从上面两点我们找到思路,我们先从后序遍历入手,每一个后序遍历的最后一个结点就是根节点,由根节点将中序遍历的数据划分为左右子树,再通过递归,找出左右子树的父亲结点,又由父亲结点将剩下的数据继续划分为左右子树。
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
//通过哈希表来保存结点值与结点位置
HashMap<Integer,Integer> map=new HashMap<>();
//将postorder赋值给post方便在build方法中获取后序遍历的最后一个值
int[] post;
public TreeNode buildTree(int[] inorder, int[] postorder) {
post=postorder;
for(int i=0;i<inorder.length;i++){
map.put(inorder[i],i); //for循环将中序遍历存入哈希表
}
return build(0,inorder.length-1,0,postorder.length-1);
}
public TreeNode build(int inorderstart,int inorderend,int postorderstart,int postorderend){
if(inorderend<inorderstart||postorderend<postorderstart) return null;
int rootval=post[postorderend]; //获取后序遍历最后一个结点的值
int rootnumber=map.get(rootval); //获取结点位置方便将中序遍历的数据分为左右子树
TreeNode node=new TreeNode(rootval);//创建结点
node.left=build(inorderstart,rootnumber-1,postorderstart,postorderstart+rootnumber-inorderstart-1); //左子树开始寻找父亲结点,并且将剩下的结点也分割为左右子树
node.right=build(rootnumber+1,inorderend,postorderstart+rootnumber-inorderstart,postorderend-1); //右子树开始寻找父亲结点,并且将剩下的结点也分割为左右子树
return node;
}
}