从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。
示例1:
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]
解题思路
根据给定的前序遍历和中序遍历序列构造二叉树,可以通过递归的方式来实现。
- 1、前序遍历序列的第一个节点是根节点,在中序遍历序列中找到根节点的位置,将中序遍历序列分为左子树序列和右子树序列。
- 2、根据左子树序列和右子树序列的长度,将前序遍历序列也分为左子树序列和右子树序列。
- 3、分别递归构造左子树和右子树,并连接到根节点上。
Java实现
public class ConstructBinaryTree {
static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val) {
this.val = val;
}
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length != inorder.length || preorder.length == 0) {
return null;
}
return buildTreeHelper(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
private TreeNode buildTreeHelper(int[] preorder, int preStart, int preEnd, int[] inorder, int inStart, int inEnd) {
if (preStart > preEnd || inStart > inEnd) {
return null;
}
// 根节点的值是先序遍历的第一个节点的值
int rootValue = preorder[preStart];
TreeNode root = new TreeNode(rootValue);
// 在中序遍历中找到根节点的位置
int rootIndexInorder = inStart;
while (rootIndexInorder <= inEnd && inorder[rootIndexInorder] != rootValue) {
rootIndexInorder++;
}
// 计算左子树的长度
int leftTreeLength = rootIndexInorder - inStart;
// 递归构建左右子树
root.left = buildTreeHelper(preorder, preStart + 1, preStart + leftTreeLength, inorder, inStart, rootIndexInorder - 1);
root.right = buildTreeHelper(preorder, preStart + leftTreeLength + 1, preEnd, inorder, rootIndexInorder + 1, inEnd);
return root;
}
// 示例测试
public static void main(String[] args) {
ConstructBinaryTree solution = new ConstructBinaryTree();
int[] preorder = {3, 9, 20, 15, 7};
int[] inorder = {9, 3, 15, 20, 7};
TreeNode root = solution.buildTree(preorder, inorder);
// 可以在这里对构建的二叉树进行操作或遍历
printPreTree(root);
System.out.println("-----------");
printInorderTree(root);
}
// 先序打印二叉树结构
private static void printPreTree(TreeNode root) {
if (root == null) {
return;
}
System.out.println(root.val);
printPreTree(root.left);
printPreTree(root.right);
}
// 中序打印二叉树结构
private static void printInorderTree(TreeNode root) {
if (root == null) {
return;
}
printInorderTree(root.left);
System.out.println(root.val);
printInorderTree(root.right);
}
}
时间空间复杂度
- 时间复杂度:O(n),其中n是二叉树中的节点数。
- 空间复杂度:O(n),需要额外的空间来存储中序遍历序列的映射关系。