重建二叉树-牛客网-剑指offer

1.问题描述

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

2.问题分析

  2.1首先了解二叉树的结构

2.2了解二叉树的三种遍历顺序(前序遍历,中序遍历和后序遍历)

    前序遍历:中左右

中序遍历:左中右

后序遍历:左右中

  根据前序遍历序列和中序遍历序列,或后序遍历序列和中序遍历序列,能唯一确定二叉树。

  2.3迭代的编程思想

3.源代码

package www.nowcoder.com.conquerOffer.binaryTree;

import java.util.Arrays;

/**
 * 重建二叉树
 * 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
 * http://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
 * @author sunny
 *
 */
public class BinaryTreeRebuild {
    /**
     * 重建二叉树
     * @param pre 前序遍历序列数组
     * @param in 中序遍历序列数组
     * @return 二叉树根节点
     */
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        //第一步:校验前序遍历序列或中序遍历序列数组是否为空
        if(null == pre || null == in || pre.length <= 0 || in.length <= 0)
            return null;
        //第二步:从前序遍历序列中获取根节点的值
        int rootVal = pre[0];
        //第三步:设置根节点的值
        TreeNode rootNode = new TreeNode(rootVal);
        //第四步:获取根节点在中序遍历序列中的索引值
        int rootIndex = findInArray(in, rootVal);    //数组工具类自带的二分查找算法
        //第五步:获取左子树的前序遍历序列、右子树的前序遍历序列,左子树的中序遍历序列、右子树的中序遍历序列
        //左子树的前序遍历序列
        int[] preLeft = Arrays.copyOfRange(pre, 1, rootIndex+1);
        //右子树的前序遍历序列
        int[] preRight = Arrays.copyOfRange(pre, rootIndex+1, pre.length);
        //左子树的中序遍历序列
        int[] inLeft = Arrays.copyOfRange(in, 0, rootIndex);
        //右子树的中序遍历序列
        int[] inRight = Arrays.copyOfRange(in, rootIndex+1, pre.length);
        BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
        //第六步:构建左子树和右子树
        TreeNode leftTree = binaryTreeRebuild.reConstructBinaryTree(preLeft, inLeft);
        TreeNode rightTree = binaryTreeRebuild.reConstructBinaryTree(preRight, inRight);
        //第七步:设置根节点的左子树和右子树
        rootNode.setLeft(leftTree);
        rootNode.setRight(rightTree);
        return rootNode;
    }

    /**
     * 获取数组中目标的下标
     * @param arr 数组
     * @param target 查找的目标
     * @return
     */
    private static int findInArray(int[] arr, int target) {
        //数组为空
        if(null == arr || arr.length <= 0)
            return -1;
        for(int i = 0; i < arr.length; i++){
            if(target == arr[i])
                return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        //前序遍历序列
        int[] pre = new int[]{1,2,4,7,3,5,6,8};
        //中序遍历序列
        int[] in = new int[]{4,7,2,1,5,3,8,6};
        BinaryTreeRebuild binaryTreeRebuild = new BinaryTreeRebuild();
        TreeNode rootNode = binaryTreeRebuild.reConstructBinaryTree(pre, in);
        System.out.println(rootNode);
    }

}

/**
 * 二叉树节点
 * @author sunny
 *
 */
class TreeNode {
    int val;    //节点值
    TreeNode left;    //左子树
    TreeNode right;    //右子树
    TreeNode(int x) { val = x; }    //构造函数
    //左子树的set方法
    public void setLeft(TreeNode left) {
        this.left = left;
    }
    //右子树的set方法
    public void setRight(TreeNode right) {
        this.right = right;
    }
}

4.运行效果

1 [email protected]

运行效果

时间: 2024-11-03 21:18:49

重建二叉树-牛客网-剑指offer的相关文章

牛客网剑指Offer习题集题解0

https://www.nowcoder.com/ta/coding-interviews 牛客个人界面欢迎互fo 0x00 二维数组中的查找 没啥难得,直接上二分就好了.注意二分别写挫了. 时间复杂度为\(O(nlogn)\) class Solution { public: bool Find(int target, vector<vector<int> > array) { int siz = (int)array.size(); for(int i=0;i<siz;+

二维数组中的查找-牛客网-剑指offer

1.问题描述 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 2.问题分析 水平方向.垂直方向二重循环查找 3.源代码 package www.nowcoder.com.conquerOffer.array; /** * 二维数组中的查找 * 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整

二叉树层次遍历(剑指Offer面试题32:从上到下打印二叉树)

图1所示为二叉树的层次遍历,即按照箭头所指方向,按照1.2.3的层次顺序,对二叉树每个节点进行访问 (此图反映的是自左至右的层次遍历,自右至左的方式类似). 要进行层次遍历,需要建立一个队列.先将二叉树头节点入队列,然后出队列,访问该节点, 如果它有左子树,则将左子树的根结点入队:如果它有右子树,则将右子树的根结点入队.然后出队列,对出队节点访问, 如此反复直到队列为空为止. 1 import java.util.*; 2 class TreeNode 3 { 4 int val; 5 Tree

牛客_剑指offer_重建二叉树,再后续遍历_递归思想_分两端

   总结:    重建二叉树:其实就是根据前序和中序重建得到二叉树,得到后续,只要输出那边设置输出顺序即可 [编程题]重建二叉树 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 完整通过代码: 先新建一个二叉树的类 public class TreeNode { int val; TreeNode left

二叉树的深度(剑指offer)递归

二叉树的深度 参与人数:1446时间限制:1秒空间限制:32768K 通过比例:40.86% 最佳记录:0 ms|0K(来自  殿) 题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路:每个结点如果他有左或者右结点,那么他的深度就是左子树和右子树深度最大的加一,利用递归很容易实现. #include<stdio.h> #include<algorithm> using namespace std;

二叉树的深度(剑指offer)

题目描述 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 1 /* 2 struct TreeNode { 3 int val; 4 struct TreeNode *left; 5 struct TreeNode *right; 6 TreeNode(int x) : 7 val(x), left(NULL), right(NULL) { 8 } 9 };*/ 10 class Solution { 11 public:

【剑指Offer】文章索引(未完)

下面是牛客网剑指Offer编程题的一些解题报告,目前还没刷完,会一篇篇加上来. 跳台阶 变态跳台阶 矩形覆盖 重建二叉树 替换空格 用两个栈代替队列 斐波那契数列 二进制中 1 的个数 版权声明:本文为博主原创文章,未经博主允许不得转载.

剑指offer

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1. NOTE:给出的所有元素都大于0,若数组大小为0,请返回0. 链接:https://www.nowcoder.com/questionTerminal/9f3231a991af4f55b95579b44b7a01ba来源:牛客网 剑指Offer中有这道题目的分析.这是一道二分查找的

剑指offer得意之作——顺时针打印矩阵

题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 分析: 这题是牛客网剑指offer的第十九题.顺时针打印就是按圈数循环打印,一圈包含两行或者两列,在打印的时候会出现某一圈中只包含一行,要判断从左向右打印和从右向左打印的时候是否会出现重复打印.同样 只包含一列时,要判断从上向下打