当前位置: 首页 > article >正文

【Leetcode Top 100】105. 从前序与中序遍历序列构造二叉树

问题背景

给定两个整数数组 p r e o r d e r preorder preorder i n o r d e r inorder inorder,其中 p r e o r d e r preorder preorder 是二叉树的 先序遍历 i n o r d e r inorder inorder 是同一棵树的 中序遍历,请构造二叉树并返回其根节点。

数据约束

  • 1 ≤ p r e o r d e r . l e n g t h ≤ 3000 1 \le preorder.length \le 3000 1preorder.length3000
  • i n o r d e r . l e n g t h = p r e o r d e r . l e n g t h inorder.length = preorder.length inorder.length=preorder.length
  • − 3000 ≤ p r e o r d e r [ i ] , i n o r d e r [ i ] ≤ 3000 -3000 \le preorder[i], inorder[i] \le 3000 3000preorder[i],inorder[i]3000
  • p r e o r d e r preorder preorder i n o r d e r inorder inorder无重复 元素
  • i n o r d e r inorder inorder 均出现在 p r e o r d e r preorder preorder
  • p r e o r d e r preorder preorder 保证 为二叉树的前序遍历序列
  • i n o r d e r inorder inorder 保证 为二叉树的中序遍历序列

解题过程

大体上的流程就是不断地从先序序列中确定根节点,再从中序序列中根据这个根节点的位置去划分左右子树,这样就能构建每一棵子树。
需要注意的是,用哈希表存储中序序列中每个节点出现的位置,能够避免在递归的过程中再用循环查找,能够提高效率。
通过这道题体会到的是,保证方法实现的正确性之后,剩下只要调用的时候填对参数就行了。

碎碎念:几年前第一次看这个实现的时候一窍不通,难过地掉头发。如今能不看题解自己想到定义哈希表,完整地实现出来,原来从不得其门而入到现在已经过去这么久了……

具体实现

/**
 * 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 {
    public TreeNode buildTree(int[] preorder, int[] inorder) {
        int n = preorder.length;
        // 能够确定长度的列表,在初始化的时候就定好,尽可能地避免扩容,养成好习惯
        Map<Integer, Integer> map = new HashMap<>(n);
        for(int i = 0; i < n; i++) {
            map.put(inorder[i], i);
        }
        return dfs(preorder, 0, n, 0, n, map);
    }

    private TreeNode dfs(int[] preorder, int preL, int preR, int inL, int inR, Map<Integer, Integer> map) {
        if(preL == preR) {
            return null;
        }
        // 根据左子树中元素的数量来确定某几个参数,体会一下偏移的思想
        int leftCount = map.get(preorder[preL]) - inL;
        // 其中有几个参数要加一,是因为要跳过当前节点本身
        TreeNode left = dfs(preorder, preL + 1, preL + 1 + leftCount, inL, inL + leftCount, map);
        TreeNode right = dfs(preorder, preL + 1 + leftCount, preR, inL + 1 + leftCount, inR, map);
        return new TreeNode(preorder[preL], left, right);
    }
}

http://www.kler.cn/a/444388.html

相关文章:

  • 基于 Python 解决 X 轴上点距离最小值问题
  • 使用React构建一个掷骰子的小游戏
  • 软考高项,考情学习
  • 【记录50】uniapp安装uview插件,样式引入失败分析及解决
  • IP协议详解
  • 使用Gradio编写大模型ollama客户端 -界面版
  • Python:动态粒子爱心
  • Spring IOC 和 AOP的学习笔记
  • Spring篇--xml方式整合第三方框架
  • linux CentOS系统上卸载docker
  • Android Binder 进程间通信
  • 肝了半年,我整理出了这篇云计算学习路线(新手必备,从入门到精通)
  • Diffusino Policy学习note
  • Unbuntu下怎么生成SSL自签证书?
  • 聊聊开源的虚拟化平台--PVE
  • 02、10个富士胶片模拟的设置
  • 使用 Canal 监听 MySQL Binlog 日志实现最终一致性
  • 《算法SM3》题目
  • 零基础开始学习鸿蒙开发-交友软件页面设计
  • 【开源免费】基于Vue和SpringBoot的靓车汽车销售网站(附论文)
  • 系统移植——Linux 内核顶层 Makefile 详解
  • 谈谈网络流量控制
  • python学opencv|读取图像(十六)修改HSV图像HSV值
  • 【自用】通信内网部署rzgxxt项目_01,后端pipeDemo部署(使用nssm.exe仿照nohup)
  • 1、数据库概念和mysql表的管理
  • c语言----选择结构