【leetcode】Array——Construct Binary Tree from Preorder and Inorder Traversal(105)
2016-03-21 22:56
513 查看
题目:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
思路:使用递归。
preorder[0]是整个tree的root,在inerder中定位root,左侧的是leftTree或者leftchild,右侧的是rightTree或者rightchild。
通过root在preorder中的位置以及左右树的节点数,可以在preorder中分别定位各自的子树的root。
举个栗子:
preorder:A B D E C F inorder: D B E A F C
root为A,inorder定位A后,划分两部分,左树是D B E,右树是F C,分别递归。
左树的root可以通过preorder定位:原rootIndex+1即为B,再把左树划分。
右树的root在preorder的位置:原rootIndex+(左侧树的节点数)+1
递归的过程中,会维护inorder两个index:left和right,left和right之间构成一个子树,带解析。
左/右树的节点数,就是 left和right之间被root划分后两侧的长度。(详细见代码理解)
代码:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
思路:使用递归。
preorder[0]是整个tree的root,在inerder中定位root,左侧的是leftTree或者leftchild,右侧的是rightTree或者rightchild。
通过root在preorder中的位置以及左右树的节点数,可以在preorder中分别定位各自的子树的root。
举个栗子:
preorder:A B D E C F inorder: D B E A F C
root为A,inorder定位A后,划分两部分,左树是D B E,右树是F C,分别递归。
左树的root可以通过preorder定位:原rootIndex+1即为B,再把左树划分。
右树的root在preorder的位置:原rootIndex+(左侧树的节点数)+1
递归的过程中,会维护inorder两个index:left和right,left和right之间构成一个子树,带解析。
左/右树的节点数,就是 left和right之间被root划分后两侧的长度。(详细见代码理解)
代码:
public class Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal { public int [] preorder; public int [] inorder; public TreeNode buildTree(int[] preorder, int[] inorder) { this.preorder = preorder; this.inorder = inorder; if(preorder==null||preorder.length==0) return null; TreeNode root = new TreeNode(preorder[0]); divideInorder(preorder[0], 0, root ,0,inorder.length-1); return root; } private void divideInorder(int rootInt,int rootIntIndex,TreeNode root,int left,int right){ for(int i=left;i<=right;i++){ if(inorder[i]==rootInt){ if(i>left){ int leftRootInt = preorder[rootIntIndex+1]; TreeNode leftNode = new TreeNode(leftRootInt); root.left=leftNode; if(left+1<i){ //存在left子树 divideInorder(leftRootInt,rootIntIndex+1,leftNode,left,i-1); } } if(i<right){ int rightRootInt = preorder[rootIntIndex+i-left+1]; TreeNode rightNode = new TreeNode(rightRootInt); root.right=rightNode; if(i+1<right){ //存在right子树 divideInorder(rightRootInt, rootIntIndex+i-left+1, rightNode, i+1, right); } } } } } }思路(改进):用HashMap存放inorder信息,这样在preorder中定位根节点后可以直接查询map就可知root在inorder中的位置,不用再次遍历。
public class Construct_Binary_Tree_from_Preorder_and_Inorder_Traversal { public int [] preorder; public Map<Integer,Integer> inorderMap = new HashMap<>(); public TreeNode buildTree(int[] preorder, int[] inorder) { this.preorder = preorder; if(preorder==null||preorder.length==0) return null; for(int i=0;i<inorder.length;i++) inorderMap.put(inorder[i], i); TreeNode root = new TreeNode(preorder[0]); divideInorder(preorder[0], 0, root ,0,inorder.length-1); return root; } private void divideInorder(int rootInt,int rootIntIndex,TreeNode root,int left,int right){ int i = inorderMap.get(rootInt); if(i>left){ int leftRootInt = preorder[rootIntIndex+1]; TreeNode leftNode = new TreeNode(leftRootInt); root.left=leftNode; if(left+1<i){ //存在left子树 divideInorder(leftRootInt,rootIntIndex+1,leftNode,left,i-1); } } if(i<right){ int rightRootInt = preorder[rootIntIndex+i-left+1]; TreeNode rightNode = new TreeNode(rightRootInt); root.right=rightNode; if(i+1<right){ //存在right子树 divideInorder(rightRootInt, rootIntIndex+i-left+1, rightNode, i+1, right); } } } }
相关文章推荐
- iOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry)
- CodeForces 321A Ciel and Robot(数学模拟 枚举答案)
- 关于linux系统端口查看和占用的解决方案
- 比较s+=4;和s=s+4;的不同
- Python 标准库 urllib2 的使用细节
- go语言在linux平台上的搭建
- HDU 2159 FATE ,完全背包
- ECMAScript5防篡改对象
- [json]Json 入门
- 第三周作业,关于老师的一个问题给出了一点自己的想法
- 路径 (Path)–nodejs
- ios打包ipa的四种实用方法(.app转.ipa)-备
- Ubuntu系统 VI 编辑器初试
- 算法总结(第二篇)
- 前面两篇安装的文字,关于root密码初始化修改不是很明显
- JavaScript 中文字符占两个字节处理方法
- 尝试新的东西
- [小技巧]导文件超出php或nginx超时时间,怎们办?
- IP验证正则表达式
- 成员内部类,静态内部类,匿名内部类,局部内部类