您的位置:首页 > 职场人生

【刷题】面试题07. 重建二叉树

2020-04-02 18:37 671 查看

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
重建二叉树的更具给出的两个列表重建出二叉树(不能没有中序遍历)。
前序(后序)遍历能确定出根节点。中序遍历能确定出左右子树的所有节点。
思路一:递归实现,处理将情况分为左子树和右子树实现。

/**
* Definition for a binary tree node.
* public class TreeNode {
*     int val;
*     TreeNode left;
*     TreeNode right;
*     TreeNode(int x) { val = x; }
* }
*/
class Solution{
public TreeNode buildTree(int[] preorder, int[] inorder) {
//preorder前序遍历 inorder中序遍历
if(preorder==null||preorder.length==0){
return null;
}
Map<Integer,Integer> hashMap=new HashMap<Integer,Integer>();
//hashMap可以快速读取出中序遍历的位置。
int length=preorder.length;
for (int i=0;i<inorder.length;i++){
hashMap.put(inorder[i],i);//这里是节点值在前,其在列表的顺序在后
}
return treeBuild(preorder,0,length-1,inorder,0,length-1,hashMap);

}
public TreeNode treeBuild(int[] preorder,int pStart,int pEnd,int[] inorder,int iStart,int iEnd,Map<Integer,Integer> hashMap){
if(pStart>pEnd){//当前为叶子节点(java中二叉树的叶子节点一部分为null节点)
return null;
}
int nodeVal=preorder[pStart];//获取当前需要处理的节点值
TreeNode treeNode=new TreeNode(nodeVal);//实例化本节点。
if(pStart==pEnd){//当前节点为叶子节点
return treeNode;//每个方法栈会返回一个节点的值(也就是说时间复杂度O(N),空间复杂度O(n))
}else{
int nodeIndex=hashMap.get(nodeVal);//获取当前节点的位置
int leftNodes=nodeIndex-iStart,rightNodes=iEnd-nodeIndex;
//leftnodes确定出当前节点的所有左子节点数量,rightnodes确定出当前节点的右子节点数量
TreeNode leftTree=treeBuild(preorder,pStart+1,pStart+leftNodes,inorder,iStart, nodeIndex-1,hashMap);
//这个递归操作出当前节点的左子树节点,这里就可以说明刚才的是确定的是节点的数量
TreeNode rightTree=treeBuild(preorder,pEnd-rightNodes+1,pEnd,inorder,nodeIndex+1, iEnd,hashMap);
//这个递归操作出当前节点的右子树节点
treeNode.left=leftTree;//将结果添加到当前节点
treeNode.right=rightTree;//将结果添加到当前节点
return treeNode;//每个方法栈会返回一个节点的值
}

}
}

思路二:利用栈的特性实现重构二叉树

class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || preorder.length == 0) {
return null;
}
TreeNode root = new TreeNode(preorder[0]);
int length = preorder.length;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
int inorderIndex = 0;
for (int i = 1; i < length; i++) {
int preorderVal = preorder[i];
TreeNode node = stack.peek();
if (node.val != inorder[inorderIndex]) {
node.left = new TreeNode(preorderVal);
stack.push(node.left);
} else {
while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {
node = stack.pop();
inorderIndex++;
}
node.right = new TreeNode(preorderVal);
stack.push(node.right);
}
}
return root;
}
}
  • 点赞
  • 收藏
  • 分享
  • 文章举报
xiaolu_333 发布了30 篇原创文章 · 获赞 0 · 访问量 465 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: