首页 > 其他分享 >力扣(LeetCode)106. 从中序与后序遍历序列构造二叉树

力扣(LeetCode)106. 从中序与后序遍历序列构造二叉树

时间:2024-11-09 18:50:39浏览次数:3  
标签:inBegin int 106 postBegin 力扣 二叉树 数组 inorder postorder

一、目标

    给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

二、代码分析

总体代码:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    //声明map,因为后续涉及频繁索引操作,而数字无法根据数值直接返回索引,用一个map来存

    HashMap<Integer, Integer> map;
    public TreeNode buildTree(int[] inorder, int[] postorder) {
        map = new HashMap<>();
        //遍历数组,将数组中的值作为key,对应值的索引作为value,传入map中储存
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        //调取Get方法,该方法会返回创建的二叉树的根节点

        return Get(inorder, 0, inorder.length, postorder, 0, postorder.length);
    }

    /*传入参数分别为inorder数组,当前选择的中序数组起始索引inBegin, 当前选择的中序数组                                                    
      终止索引inEnd,后序数组postorder,当前选择的后序数组起始索引postBegin,当前选择的                        
      后序数组终止索引postEnd,
    */

    public TreeNode Get(int[] inorder, int inBegin, int inEnd, int[] postorder, 
                        int postBegin, int postEnd)
        {

        //递归终止判断条件

        if(inBegin >= inEnd || postBegin >= postEnd){
            return null;
            }
        TreeNode root = new TreeNode();

        //拿到后序数组中最后一个元素在中序数组中的索引记为rootindex

        int rootindex = map.get(postorder[postEnd - 1]);

        //记录分割出来的左子树的中序遍历长度,下面用来在后序数组中根据这个长度分割

        int leftlength = rootindex - inBegin;

        //记录当前找出的子树的根节点

        root.val = inorder[rootindex];

        //递归对当前节点左右子节点调用Get,但注意进行区间的分割
        root.left = Get(inorder, inBegin, inBegin + leftlength, postorder, 
                        postBegin, postBegin + leftlength);
        root.right = Get(inorder, rootindex + 1, inEnd, postorder, 
                         postBegin + leftlength, postEnd - 1);
        return root;
    }
}

     用一个map来存中序数组的索引和数值,因为后序涉及从值获取索引

        map = new HashMap<>();
        //遍历数组,将数组中的值作为key,对应值的索引作为value,传入map中储存
        for(int i = 0; i < inorder.length; i++){
            map.put(inorder[i], i);
        }
        //调取Get方法,该方法会返回创建的二叉树的根节点

 中序遍历顺序:左中右

 后序遍历顺序:左右中

  本方法整体思路为:
  先从后序数组中找到最后一个节点记为根节点(后序数组中找到最后一个节点一定是根节点),储存这个节点,根据根节点对中序数组进行切割,分中左序列和中右序列,然后根据中左的长度对后序数组从头开始切割分成后左序列和后右序列,再次递归调取切割函数,左节点获取需要传入中左,后左,右节点获取需要传入中右,后右,终止条件为区间起点终点相同。

    /*传入参数分别为inorder数组,当前选择的中序数组起始索引inBegin, 当前选择的中序数组                                                    
      终止索引inEnd,后序数组postorder,当前选择的后序数组起始索引postBegin,当前选择的                        
      后序数组终止索引postEnd,
    */

    public TreeNode Get(int[] inorder, int inBegin, int inEnd, int[] postorder, 
                        int postBegin, int postEnd)
        {

        //递归终止判断条件

        if(inBegin >= inEnd || postBegin >= postEnd){
            return null;
            }
        TreeNode root = new TreeNode();

        //拿到后序数组中最后一个元素在中序数组中的索引记为rootindex

        int rootindex = map.get(postorder[postEnd - 1]);

        //记录分割出来的左子树的中序遍历长度,下面用来在后序数组中根据这个长度分割

        int leftlength = rootindex - inBegin;

        //记录当前找出的子树的根节点

        root.val = inorder[rootindex];

        //递归对当前节点左右子节点调用Get,但注意进行区间的分割
        root.left = Get(inorder, inBegin, inBegin + leftlength, postorder, 
                        postBegin, postBegin + leftlength);
        root.right = Get(inorder, rootindex + 1, inEnd, postorder, 
                         postBegin + leftlength, postEnd - 1);
        return root;
    }

  获取左节点时候传入区间为中左序列(inBegin, inBegin + leftlength)和后左序列(postBegin, postBegin + leftlength)

  获取右节点时候传入区间为中右序列(rootindex + 1, inEnd)和后右序列(postBegin + leftlength, postEnd - 1)

         //递归对当前节点左右子节点调用Get,但注意进行区间的分割
        root.left = Get(inorder, inBegin, inBegin + leftlength, postorder, 
                        postBegin, postBegin + leftlength);
        root.right = Get(inorder, rootindex + 1, inEnd, postorder, 
                         postBegin + leftlength, postEnd - 1);

三、总结

  虽然是中等难度,但我觉得这道题不好写,可以作为按照特定规则递归法构造二叉树的经典题目来好好学习。

标签:inBegin,int,106,postBegin,力扣,二叉树,数组,inorder,postorder
From: https://blog.csdn.net/zzb1580/article/details/143644377

相关文章

  • 104.力扣(leetcode)二叉树的最大深度(JAVA)
    一、目标给定一个二叉树 root ,返回其最大深度。二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。二、代码分析总代码:/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*TreeN......
  • 力扣(Leetcode)112. 路径总和(JAVA)
    一、目标 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。叶子节点 是指没有子节点的节点。二、代码解读......
  • 257. 力扣(LeetCode)二叉树的所有路径(JAVA)
    一、目标给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。叶子节点 是指没有子节点的节点。二、代码解读总代码:/***Definitionforabinarytreenode.*publicclassTreeNode{*intval;*TreeNodeleft;*......
  • 代码随想录算法训练营第十七天| 654.最大二叉树 , 617.合并二叉树 , 700.二叉搜索树中的
    654.最大二叉树文章链接:https://programmercarl.com/0654.最大二叉树.html题目链接:https://leetcode.cn/problems/maximum-binary-tree/description/classSolution{public:TreeNode*traversal(vector<int>&nums,intleft,intright){if(left>=right)ret......
  • C语言数据结构之二叉树(BINARY TREE)的多种数据类型存贮
    C语言数据结构之二叉树(BINARYTREE)的多种数据类型存贮用无类型指针(void*)来做为基本数据类型来存贮数据,将其他数据类型强制转化为无类型指针,从而达到目标!!!输出函数指针BTFunc比较函数指针BTCmpFunc返回值为整型值1、-1、0,表示大于、小于、相等代码如下:/*filename:btr......
  • 二叉树常用代码合集【C++版】(详细注释)
    二叉树常用代码合集【C++版】(详细注释)关键的地方有详细的注释。如果需要更详细的注释,可以丢给大模型再注释一遍。#include<iostream>#include<memory>#include<string>#definemv(x)std::move(x)#definecoutln(x)cout<<x<<endlusingnamespacestd;......
  • 44-best-time-to-buy-and-sell-stock-with-cooldown 力扣 309. 买卖股票的最佳时机包
    买卖股票系列【leetcode】40-best-time-to-buy-and-sell-stock力扣121.买卖股票的最佳时机【leetcode】41-best-time-to-buy-and-sell-stock-ii力扣122.买卖股票的最佳时机II【leetcode】42-best-time-to-buy-and-sell-stock-iii力扣123.买卖股票的最佳时机III【le......
  • C++算法练习-day38——106.从中序和后序遍历序列构造二叉树
    题目来源:.-力扣(LeetCode)题目思路分析题目要求根据一棵二叉树的中序遍历(inorder)和后序遍历(postorder)结果重建这棵二叉树。中序遍历的特点是左子树->根节点->右子树,而后序遍历的特点是左子树->右子树->根节点。利用这两个遍历的特点,我们可以递归地重建整棵树。后序......
  • 力扣21 打卡17 设计相邻元素求和服务
    思路:该方案通过构建一个字典,将每个元素值映射到其在二维数组中的坐标位置,以便快速查找。adjacentSum方法根据指定元素的坐标,计算其上下左右相邻元素之和;diagonalSum方法则计算该元素的四个对角线相邻元素之和。每个方法通过判断相邻坐标是否在数组边界内,确保不越界访问。......
  • 7-8 数据结构实验二 二叉树的遍历
    以二叉链表作存储结构,建立一棵二叉树。输出该二叉树的先序、中序、后序遍历序列,求出该二叉树的深度,并统计其叶子结点数。二叉链表的类型描述:typedefcharElemType;typedefstructBiNode{ElemTypedata;structBiNode*lchild,*rchild;}BiNode,*BiTree;......