思路
- 如果前序遍历序列或中序遍历序列为空,则返回null
- 取前序遍历的第一个节点作为根节点
- 在中序遍历中找到根节点,将中序遍历划分为左子树和右子树
- 递归构造左子树和右子树
- 返回根节点
Java实现
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length != inorder.length) {
return null;
}
return buildTreeHelper(preorder, inorder, 0, 0, inorder.length - 1);
}
private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int preStart, int inStart, int inEnd) {
if (inStart > inEnd) {
return null;
}
int rootVal = preorder[preStart];
TreeNode root = new TreeNode(rootVal);
int rootIndex = inStart;
while (rootIndex <= inEnd && inorder[rootIndex] != rootVal) {
rootIndex++;
}
int leftSize = rootIndex - inStart;
root.left = buildTreeHelper(preorder, inorder, preStart + 1, inStart, rootIndex - 1);
root.right = buildTreeHelper(preorder, inorder, preStart + leftSize + 1, rootIndex + 1, inEnd);
return root;
}
时间复杂度
O(n)。遍历前序遍历和中序遍历每个元素一次。
空间复杂度
O(n)。递归调用需要使用栈空间,栈空间的大小取决于递归树的深度,而递归树的深度最大为n。
这里使用Markdown格式记录构建二叉树的思路和代码:
思路
- 空树返回null
- 确定根节点:前序遍历第一个节点
- 切割中序遍历为左右子树
- 递归构造左右子树
- 返回根节点
Java实现
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length != inorder.length) {
return null;
}
Map<Integer, Integer> inorderIndexMap = new HashMap<>();
for (int i = 0; i < inorder.length; i++) {
inorderIndexMap.put(inorder[i], i);
}
return buildTreeHelper(preorder, inorder, 0, 0, inorder.length - 1, inorderIndexMap);
}
private TreeNode buildTreeHelper(int[] preorder, int[] inorder, int preStart, int inStart, int inEnd, Map<Integer, Integer> inorderIndexMap) {
if (inStart > inEnd) {
return null;
}
int rootVal = preorder[preStart];
TreeNode root = new TreeNode(rootVal);
int rootIndex = inorderIndexMap.get(rootVal);
int leftSize = rootIndex - inStart;
root.left = buildTreeHelper(preorder, inorder, preStart + 1, inStart, rootIndex - 1, inorderIndexMap);
root.right = buildTreeHelper(preorder, inorder, preStart + leftSize + 1, rootIndex + 1, inEnd, inorderIndexMap);
return root;
}
时间复杂度
O(n)。遍历前序遍历和中序遍历每个元素一次。
空间复杂度
O(n)。递归调用需要使用栈空间,栈空间的大小取决于递归树的深度,而递归树的深度最大为n。
使用HashMap优化了rootIndex的查找时间复杂度为O(1)。