题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/
9 20
/
15 7
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof
题解:
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public 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 data");
}
return buildTree(preorder, 0, preLen -1, inorder, 0,inLen - 1);
}
/**
* [buildTree description]
* @param preorder 二叉树前序遍历的结果
* @param preLeft 二叉树前序遍历的左边界
* @param preRight 二叉树前序遍历的右边界
* @param inorder 二叉树中序遍历的结果
* @param inLeft 二叉树中序遍历的左边界
* @param inRight 二叉树中序遍历的右边界
* @return root [description]
*/
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, pivotIndex - inLeft + preLeft,
inorder, inLeft, pivotIndex - 1);
root.right = buildTree(preorder, pivotIndex - inLeft + preLeft + 1, preRight,
inorder, pivotIndex + 1, inRight);
return root;
}
}
时间复杂度:O(N^2),递归+while循环
空间复杂度:O(1)
优化:将中序遍历的索引和值存储在一个hash表里
import java.util.*;
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
private Map<Integer, Integer> map;
private int[] preorder;
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.map = new HashMap<>();
for (int i = 0; i < inLen; i++) {
map.put(inorder[i], i);
}
return buildTree(0, preLen -1, 0,inLen - 1);
}
/**
* [buildTree description]
* @param preorder 二叉树前序遍历的结果
* @param preLeft 二叉树前序遍历的左边界
* @param preRight 二叉树前序遍历的右边界
* @param inorder 二叉树中序遍历的结果
* @param inLeft 二叉树中序遍历的左边界
* @param inRight 二叉树中序遍历的右边界
* @return root [description]
*/
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 = map.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),额外用到的hash表