剑指Offer第4题详解(附Java、Python源码)

时间:2022-07-25
本文章向大家介绍剑指Offer第4题详解(附Java、Python源码),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1. 题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

2. 分析

(1)根据前序序列第一个结点确定根结点 (2)根据根结点在中序序列中的位置分割出左右两个子序列 (3)对左子树和右子树分别递归使用同样的方法继续分解

示例

前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

(1)根据当前前序序列的第一个结点确定根结点,为 1。 (2)找到 1 在中序遍历序列中的位置,为 in[3]。 (3)切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树。则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}。 (4)对子树分别使用同样的方法分解(使用递归较方便)。

3. 代码实现

3.1 Java 实现

1.先来棵树

class TreeNode {
    int value;
    TreeNode leftTree;
    TreeNode rightTree;
    TreeNode(int x) { value = x; }

    @Override
    public String toString() {
        return "TreeNode{" +
                "value=" + value +
                ", leftTree=" + leftTree +
                ", rightTree=" + rightTree +
                '}';
    }
}
import java.util.Arrays;
public class JzOffer4 {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if (pre.length == 0 || in.length == 0) {
            return null;
        }
        // 先根据先序遍历建立根结点
        TreeNode root = new TreeNode(pre[0]);

        for (int i=0;i<in.length;i++) {
            if (in[i] == pre[0]) {
                /**
                 * 递归构建左右子树
                 * 注意 copyOfRange 函数,左闭右开
                 */
                root.leftTree = reConstructBinaryTree(Arrays.copyOfRange(pre, 1,i+1 ), Arrays.copyOfRange(in, 0, i));
                root.rightTree = reConstructBinaryTree(Arrays.copyOfRange(pre, i+1, pre.length), Arrays.copyOfRange(in, i+1, in.length));
                break;
            }
        }
        return root;
    }

    public static void main(String[] args) {
        int[] pre = {1,2,4,7,3,5,6,8};
        int[] in = {4,7,2,1,5,3,8,6};
        System.out.println(new JzOffer4().reConstructBinaryTree(pre,in).toString());
    }
}

3.2 Python 实现

# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    # 返回构造的TreeNode根节点
    def reConstructBinaryTree(self, pre, tin):
        # write code here
        prelen = len(pre)
        tinlen = len(tin)
        if prelen == 0 | tinlen == 0 :
            return None
        root = TreeNode(pre[0])
        for i in range(tinlen):
            if tin[i] == pre[0]:
                root.left = self.reConstructBinaryTree(pre[1:i+1], tin[0:i])
                root.right = self.reConstructBinaryTree(pre[i+1:prelen], tin[i+1:tinlen])
                break
        return root