根据前序遍历和中序遍历树构造二叉树.您在真实的面试中是否遇到过这个题?
Yes
样例
给出中序遍历:[1,2,3]和前序遍历:[2,1,3]. 返回如下的树:
2
/ \
1 3
注意
你可以假设树中不存在相同数值的节点
标签 Expand
解题思路:
前序遍历表示第一个节点必然是一个根节点root,中序遍历找到与root一样的节点,该节点的左边就是左子树的中旬遍历长度为leftlen,该节点的后边就是右子树的中旬遍历长度为rightlen。前序遍历除了根节点长为leftlen的数组为左子树的前序遍历,前序遍历除了根节点和长为leftlen的数组为左子树,剩下的就是长度为rightlen数组既是root节点的右子树前序遍历。递归实现即可。
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
*@param preorder : A list of integers that preorder traversal of a tree
*@param inorder : A list of integers that inorder traversal of a tree
*@return : Root of a tree
*/
public TreeNode buildTree(int[] preorder, int[] inorder) {
// write your code here
if(null==preorder||null==inorder||0==preorder.length||0==inorder.length) return null;
if (1 == inorder.length) return new TreeNode(inorder[0]);
int root = preorder[0];
TreeNode res = new TreeNode(root);
int left = 0;
while(inorder[left]!=root){
left++;
}
res.left = buildTree(getArray(preorder, 1, left), getArray(inorder, 0, left-1));
res.right = buildTree(getArray(preorder, left+1, preorder.length-1), getArray(inorder, left+1, inorder.length-1));
return res;
}
public int[] getArray(int[] ora, int s, int e) {
int[] res = new int[e - s + 1];
int tmp = s;
for (int i = 0; i <= e - s; i++) {
res[i] = ora[tmp++];
}
return res;
}
}