题目描述
涉及tag
算法思路
构造一棵二叉树需要知道前序遍历和中序遍历的左边界和右边界。
前序遍历的顺序是根节点、左子树、右子树,而中序遍历的顺序是左子树、根节点、右子树,拿前序的第一个节点寻找中序中的和该节点相同的节点,中序中根节点左侧就是左子树,右侧就是右子树。
本题采用递归调用的方式进行构造,用先序遍历和中序遍历里左右子树的边界的索引进行对树的描述。如示例代码1。
引入哈希表简化查找中序中根节点的索引,简化时间复杂度,如示例代码2。
示例代码1
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen) {
throw new RuntimeException("Incorrect input");
}
return buildTree(preorder, 0, preLen - 1, inorder, 0, inLen - 1);
}
private TreeNode buildTree(int[] preorder, int preLeft, int preRight, int[] inorder, int inLeft, int inRight) {
if(preLeft> preRight || inLeft > inRight) {
return null;
}
int pivot = preorder[preLeft];
TreeNode root = new TreeNode(pivot);
int pivotIndex = inLeft;
while (inorder[pivotIndex] != pivot) {
pivotIndex++;
}
root.left = buildTree(preorder, preLeft + 1, preLeft + pivotIndex - inLeft, inorder, inLeft, pivotIndex - 1);
root.right = buildTree(preorder, preLeft + pivotIndex - inLeft + 1, preRight, inorder, pivotIndex + 1, inRight);
return root;
}
}
时间复杂度:采用递归方式构建二叉树,创建n个节点,每个节点O(1)。遍历中序数组找到根节点的索引需要O(n),总时间复杂度O(n²)。
示例代码2
import java.util.HashMap;
import java.util.Map;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
private int[] preorder;
private Map<Integer, Integer> hash;
public TreeNode buildTree(int[] preorder, int[] inorder) {
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen) {
throw new RuntimeException("Incorrect input data.");
}
this.preorder = preorder;
this.hash = new HashMap<>();
for (int i = 0; i < inLen; i++) {
hash.put(inorder[i], i);
}
return buildTree(0, preLen - 1, 0, inLen - 1);
}
private TreeNode buildTree(int preLeft, int preRight, int inLeft, int inRight) {
// 因为是递归调用的方法,按照国际惯例,先写递归终止条件
if (preLeft > preRight || inLeft > inRight) {
return null;
}
// 先序遍历的起点元素很重要
int pivot = preorder[preLeft];
TreeNode root = new TreeNode(pivot);
int pivotIndex = hash.get(pivot);
root.left = buildTree(preLeft + 1, pivotIndex - inLeft + preLeft, inLeft, pivotIndex - 1);
root.right = buildTree(pivotIndex - inLeft + preLeft + 1, preRight, pivotIndex + 1, inRight);
return root;
}
}
时间复杂度:O(n)
空间复杂度:O(n)