105. Construct Binary Tree from Preorder and Inorder Traversal
题目:
Given preorder and inorder traversal of a tree, construct the binary tree.
Note:
You may assume that duplicates do not exist in the tree.
链接: http://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
题解:
根据前序遍历和中序遍历重建二叉树,方法是自顶向下recursive来构建。前序就是 root -> left -> right,中序是 left -> root -> right。所以每次preorder[preLo]就是root。接下来preorder[preLo + 1]就是当前root的left child, 接下来在inorder中找到root的index - rootAtInorder,则 inorder[rootAtInOrder + 1]就是当前root的right child。最后做递归的时候要注意,求left child时,inHi = rootAtInOrder - 1,求right child时, inLo = rootAtInOrder + 1。 应该还有不少更简便的方法,要好好想一想。
Time Complexity - O(n), Space Complexity - O(n)。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { if(preorder == null || inorder == null || preorder.length != inorder.length || preorder.length == 0) return null; return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode buildTree(int[] preorder, int preLo, int preHi, int[] inorder, int inLo, int inHi) { if(preLo > preHi || inLo > inHi) return null; TreeNode root = new TreeNode(preorder[preLo]); int rootAtInorder = 0; for(int i = inLo; i <= inHi; i++) { if(inorder[i] == root.val) { //because no duplicate rootAtInorder = i; break; } } int leftSubTreeLen = rootAtInorder - inLo; root.left = buildTree(preorder, preLo + 1, preLo + leftSubTreeLen, inorder, inLo, rootAtInorder - 1); root.right = buildTree(preorder, preLo + leftSubTreeLen + 1, preHi, inorder, rootAtInorder + 1, inHi); return root; } }
Discussion里还有一些很好的写法, 比如使用一个stack进行iterative重建;或者不做辅助函数,使用arrays.copyof,把原array分割后分别递归计算left child和right child。
要多思考多练习。
PS: 今天 Twitter裁员 8%, 好吓人。
二刷:
方法和一刷一样,就是使用递归来重建树。找到根节点以后,求出左子树长度和右子树长度,然后分别递归调用辅助方法求出左child和右child,最后返回root就可以了。各种边界要想得细一点。
可以使用HashMap保存inorder的key, value,这样在递归调用辅助方法时可以O(1)拿到rootVal,就不用顺序搜索了。 (下一道题也是一样)
Java:
Time Complexity - O(n), Space Complexity - O(n)。
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Solution { public TreeNode buildTree(int[] preorder, int[] inorder) { if (preorder == null || inorder == null || preorder.length != inorder.length || preorder.length == 0) return null; return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1); } private TreeNode buildTree(int[] preorder, int preLo, int preHi, int[] inorder, int inLo, int inHi) { if (preLo > preHi || inLo > inHi) return null; int rootVal = preorder[preLo]; TreeNode root = new TreeNode(rootVal); int rootIndexAtInorder = inLo; while (rootIndexAtInorder <= inHi) { if (inorder[rootIndexAtInorder] == rootVal) break; rootIndexAtInorder++; } int leftTreeLen = rootIndexAtInorder - inLo; root.left = buildTree(preorder, preLo + 1, preLo + leftTreeLen, inorder, inLo, rootIndexAtInorder - 1); root.right = buildTree(preorder, preLo + leftTreeLen + 1, preHi, inorder, rootIndexAtInorder + 1, inHi); return root; } }
Reference:
https://leetcode.com/discuss/63586/neat-java-solution-pretty-easy-to-read
https://leetcode.com/discuss/2297/the-iterative-solution-is-easier-than-you-think
https://leetcode.com/discuss/28271/my-o-n-19ms-solution-without-recusion-hope-help-you
https://leetcode.com/discuss/18101/sharing-my-straightforward-recursive-solution
https://leetcode.com/discuss/12179/my-accepted-java-solution
https://leetcode.com/discuss/32414/recursive-solution-in-java