zoukankan      html  css  js  c++  java
  • 剑指offer_(4)

    重建二叉树:

    题目描述

    输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
    例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
     
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode(int x){
            val = x;
        }
    }
     1 import java.util.HashMap;
     2 
     3 /**
     4  * 先序数组: 1,2,4,7,3,5,6,8 中序数组:4,7,2,1,5,3,8,6
     5  * 思路:1.先序数组中最左边的值就是树的头节点值,记为和,并且用h生成
     6  *          头节点,记为head。然后在中序数组中找到h,假设位置为i。那么在
     7  *          中序数组中,i左边的数组就是头节点左子树的中序数组,假设长度
     8  *          为L,则左子树的先序数组就是先序数组中h往右长度也为L的数组
     9  *          例如:二叉树头节点的值为1,在数组中找到1的位置,1的左边数组为
    10  *          4,7,2 是头节点左子树的中序数组,长度为3; 先序数组中1的右边长度
    11  *          也是3的数组为:2,4,7 , 也就是左子树的先序数组。
    12  *      2. 用左子树的先序和中序数组,递归整个过程建立左子树,返回的头节点记为left。
    13  *      3. i右边的数组就是头结点右子树的中序数组,假设长度为r。先序数组中右侧等长
    14  *          部分就是头节点右子树的先序数组。
    15  *          例如:中序数组中1的右边数组为:5,3,8,6,长度为4; 先序数组右侧等长的部分为:
    16  *          3,5,6,8,他们分别是头节点右子树的中序和先序数组。
    17  *      4. 用右子树的先序和中序数组,递归整个过程建立右子树,返回的节点记为right。
    18  *      5. 把head的左孩子和有孩子分别设为left和right,返回head,过程结束。
    19  *
    20  *      如果二叉树的节点数为N,在中序数组中找到位置i的过程可以用哈希表来实现,这样整个
    21  *      过程时间复杂度为O(n)。
    22  */
    23 public class Solution {
    24 
    25     public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
    26         if(pre == null || in == null){
    27             return null;
    28         }
    29         HashMap<Integer, Integer> map = new HashMap<>();
    30         for(int i=0; i < in.length; i++){
    31             map.put(in[i],i);
    32         }
    33         return preIn(pre, 0, pre.length -1 , in, 0, in.length -1, map);
    34     }
    35 
    36     /**
    37      * 递归函数
    38      * @param p 前序数组
    39      * @param pi 前序数组的初始下标
    40      * @param pj 前序数组的结束下标
    41      * @param n 中序数组
    42      * @param ni 中序数组的初始下标
    43      * @param nj 中序数组的结束下标
    44      * @param map 中序值和位置的map集合
    45      * @return
    46      */
    47     public TreeNode preIn(int[] p, int pi, int pj, int[] n, int ni, int nj, HashMap<Integer,Integer> map){
    48 
    49         if(pi > pj){
    50             return null;
    51         }
    52         //头节点
    53         TreeNode head = new TreeNode(p[pi]);
    54         //头节点在中序的位置
    55         int index = map.get(p[pi]);
    56         head.left = preIn(p, pi + 1, pi + index - ni, n, ni, index  -1, map);
    57         head.right = preIn(p, pi + index - ni + 1, pj, n, index + 1, nj, map);
    58         return head;
    59     }
    60 
    61 }
  • 相关阅读:
    uva 11997
    【USACO 3.1.1】最短网络
    【USACO 2.4.5】分数化小数
    【USACO 2.4.4】回家
    【USACO 2.4.3】牛的旅行
    【USACO 2.4.2】穿越栅栏
    【USACO 2.4.1】两只塔姆沃斯牛
    【USACO 2.3.5】控制公司
    【USACO 2.3.4】货币系统
    【USACO 2.3.3】零数列
  • 原文地址:https://www.cnblogs.com/huangyichun/p/5961973.html
Copyright © 2011-2022 走看看