题目
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
解答
分为以下几步:
- 如果左边界索引小于右边界索引,说明遍历序列为空,返回一个空树 null 。
- 如果左边界索引等于右边界索引,说明到达叶子节点,直接创建一个节点并返回。
- 前序遍历的第一个值就是根节点的值。根据这个根节点的值在中序遍历的数组内找到根节点所在的索引位置 index 。
- 创建一个根节点 root。
- 根据找到的中序遍历数组里根节点所在的索引位置分别创建左右子树并与根节点 root 建立连接关系。
代码
/**
* 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) {
return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
private TreeNode buildTree(int[] preorder, int pl, int pr, int[] inorder, int il, int ir) {
if(pr < pl) return null;
if(pr == pl) return new TreeNode(preorder[pl]);
int rootVal = preorder[pl];
int index = -1;
for(int i = il; i <= ir; i ++) {
if(inorder[i] == rootVal) {
index = i;
break;
}
}
if(index == -1) {
throw new RuntimeException("不能构造出二叉树!");
}
TreeNode root = new TreeNode(rootVal);
if(index > il) {
root.left = buildTree(preorder, pl + 1, pl + (index - il), inorder, il, index - 1);
}
if(index < ir) {
root.right = buildTree(preorder, pl + (index - il) + 1, pr, inorder, index + 1, ir);
}
return root;
}
}