剑指 Offer 07. 重建二叉树

思路

  1. 如果前序遍历序列或中序遍历序列为空,则返回null
  2. 取前序遍历的第一个节点作为根节点
  3. 在中序遍历中找到根节点,将中序遍历划分为左子树和右子树
  4. 递归构造左子树和右子树
  5. 返回根节点

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格式记录构建二叉树的思路和代码:

思路

  1. 空树返回null
  2. 确定根节点:前序遍历第一个节点
  3. 切割中序遍历为左右子树
  4. 递归构造左右子树
  5. 返回根节点

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)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值