LeetCode 449. Serialize and Deserialize BST【树,BFS,DFS,栈】困难
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。
为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。
由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。
序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
示例 1:
输入:root = [2,1,3]
输出:[2,1,3]
示例 2:
输入:root = []
输出:[]
提示:
- 树中节点数范围是
[0, 10^4] 0 <= Node.val <= 10^4- 题目数据 保证 输入的树是一棵二叉搜索树。
类似题目:
- 449. 序列化和反序列化二叉搜索树
- 297. 二叉树的序列化与反序列化 困难
- 428. 序列化和反序列化 N 叉树 困难
二叉搜索树是一种特殊的二叉树,序列化和反序列化过程也可以直接使用「297. 二叉树的序列化与反序列化」中的方法,即实现上我们可以忽略「BST」这一条件,使用BFS或DFS、存储空节点来进行序列号和反序列化。由于点的数量是 1 e 4 1e4 1e4 ,最坏情况下是当BST成链时,会有较大的空间浪费。
但二叉搜索树的特殊之处在于其中序遍历是有序的,可以利用这一点来优化时间和空间复杂度。
解法 二叉搜索树+后序遍历+栈
给定一棵二叉树的「先序遍历」和「中序遍历」可以恢复这颗二叉树。给定一棵二叉树的「后序遍历」和「中序遍历」也可以恢复这颗二叉树。而对于二叉搜索树,给定「先序遍历」或者「后序遍历」,对其经过排序即可得到「中序遍历」。因此,仅对二叉搜索树做「先序遍历」或者「后序遍历」,即可达到序列化和反序列化的要求。此题解采用「后序遍历」的方法。
- 序列化时,只需要对二叉搜索树进行后序遍历(注意跳过空节点),再将数组编码成字符串即可。
- 反序列化时,需要先将字符串解码成后序遍历的数组。在将后序遍历的数组恢复成二叉搜索树时,不需要先排序得到中序遍历的数组、再根据中序和后序遍历的数组来恢复二叉树,而可以根据有序性直接由后序遍历的数组恢复二叉搜索树——后序遍历得到的数组中,根结点的值位于数组末尾,左子树的节点均小于根节点的值,右子树的节点均大于根节点的值,可以根据这些性质设计递归函数恢复二叉搜索树。
public class Codec {// Encodes a tree to a single string.public String serialize(TreeNode root) {return postOrder(root, new StringBuilder()).toString();}private StringBuilder postOrder(TreeNode root, StringBuilder sb) {if (root != null) { // 可以不用存储空指针sb = postOrder(root.left, sb);sb = postOrder(root.right, sb);sb.append(String.valueOf(root.val) + ",");}return sb;}// Decodes your encoded data to tree.public TreeNode deserialize(String data) {if (data.isEmpty()) return null;String[] arr = data.split(",");Deque<Integer> stack = new ArrayDeque<Integer>();int length = arr.length;for (int i = 0; i < length; ++i)stack.push(Integer.parseInt(arr[i]));return construct(Integer.MIN_VALUE, Integer.MAX_VALUE, stack);}// 使用栈和后序遍历重构二叉搜索树private TreeNode construct(int lower, int upper, Deque<Integer> stack) {// 当前元素超出范围,不能用作子树根节点的值if (stack.isEmpty() || stack.peek() < lower || stack.peek() > upper) return null;int val = stack.pop();TreeNode root = new TreeNode(val);root.right = construct(val, upper, stack);root.left = construct(lower, val, stack);return root;}
}
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n) ,其中 n n n 是树的节点数。 s e r i a l i z e serialize serialize 需要 O ( n ) O(n) O(n) 时间遍历每个点。 d e s e r i a l i z e deserialize deserialize 需要 O ( n ) O(n) O(n) 时间恢复每个点
- 空间复杂度: O ( n ) O(n) O(n) ,其中 n n n 是树的节点数。 s e r i a l i z e serialize serialize 需要 O ( n ) O(n) O(n) 空间用数组保存每个点的值,递归的深度最深也为 O ( n ) O(n) O(n) 。 d e s e r i a l i z e deserialize deserialize 需要 O ( n ) O(n) O(n) 空间用数组保存每个点的值,递归的深度最深也为 O ( n ) O(n) O(n) 。
相关文章:
LeetCode 449. Serialize and Deserialize BST【树,BFS,DFS,栈】困难
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
嵌入式IDE(1):IAR中ICF链接文件详解和实例分析
最近在使用NXP的提供的MCUXPresso IDE,除了Eclipse固有的优点外,我觉得它最大的优点就是在链接脚本的生成上,提供了非常直观的GUI配置界面。但这个IDE仅仅支持NXP相关的产品,而且调试的性能在某些情况下并不理想。而我们用得比较多…...
分布式版本控制工具——git
✅<1>主页::我的代码爱吃辣 📃<2>知识讲解:Linux——git ☂️<3>开发环境:Centos7 💬<4>前言:git是一个开源的分布式版本控制系统,可以有效、高速地处理从很…...
C基础-数组
1.一维数组的创建和初始化 int main() {// int arr1[10];int n 0;scanf("%d",&n);//int count 10;int arr2[n]; //局部的变量,这些局部的变量或者数组是存放在栈区的,存放在栈区上的数组,如果不初始化的话,默认…...
springboot项目配置flyway菜鸟级别教程
1、Flyway的工作原理 Flyway在第一次执行时,会创建一个默认名为flyway_schema_history的历史记录表,这张表会用来跟踪或记录数据库的状态,然后每次项目启动时都会自动扫描在resources/db/migration下的文件的版本号并且通过查询flyway_schem…...
成都精灵云初试
最近参加了成都精灵云的笔试与面试,岗位是c工程师。后面自己复盘了过程,初试部分总结如下,希望能对各位相进该公司以及面试C工程师的同学提供一些参考。这也是博主第一次参加面试,很多东西都还没准备,很多答得不好&…...
css relative 和absolute布局
1、relative和absolute内部的元素都是相对于父容器,若父容器没有指定为relative,则默认为整个文档视图空间,absolute可以重叠元素,relative则不行。relative意味着元素的任意属性如left和right都是相对于其他元素的。absolute则相…...
更健康舒适更科技的照明体验!书客SKY护眼台灯SUKER L1上手体验
低价又好用的护眼台灯是多数人的需求,很多人只追求功能性护眼台灯,显色高、无频闪、无蓝光等基础需求。但是在较低价格中很难面面俱到,然而刚发布的SUKER书客L1护眼台灯却是一款不可多得的性价比护眼台灯,拥有高品质光源ÿ…...
经管博士科研基础【19】齐次线性方程组
1. 线性方程组 2. 非线性方程组 非线性方程,就是因变量与自变量之间的关系不是线性的关系,这类方程很多,例如平方关系、对数关系、指数关系、三角函数关系等等。求解此类方程往往很难得到精确解,经常需要求近似解问题。相应的求近似解的方法也逐渐得到大家的重视。 3. 线…...
django报错解决 Forbidden (403) CSRF verification failed. Request aborted.
django报错解决 Forbidden (403) CSRF verification failed. Request aborted. 报错内容 Forbidden (403) CSRF verification failed. Request aborted.Help Reason given for failure:Origin checking failed - https://active-mantis-distinct.ngrok-free.app does not mat…...
k8s-实战——yapi平台部署
文章目录 k8s 部署yapi平台前言准备工作构建yapi镜像Dockerfileentrypoint.shbuild.sh源码下载构建镜像启动mongo数据库新建nfs服务mongo创建mongo服务初始化数据启动yapi服务创建yapi服务查看密码访问地址k8s 部署yapi平台 前言 部署yapi平台需要mo...
Excel VSTO开发5 -Excel对象结构
版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。 5 Excel对象结构 Excel提供了几个比较重要的对象: Application、Workbooks、Workbook、Worksheets、Worksheet 为了便…...
Javafx集成sqlite数据库
什么是SQLite SQLite是一款非常轻量级的关系数据库系统,支持多数SQL92标准。SQLite在使用前不需要安装设置,不需要进程来启动、停止或配置,而其他大多数SQL数据库引擎是作为一个单独的服务器进程,被程序使用某种内部进程通信(典型…...
react-native实现 TextInput 键盘显示搜索按钮并触发回调
<TextInput returnKeyType"search"returnKeyLabel"搜索"onSubmitEditing{e > {toSearch(keyword);}} /><SearchBarref{serachBarEl}placeholder"请输入"onChangeText{handleChangeSearch}value{search}onSubmitEditing{handleSearch…...
人大金仓分析型数据库备份和恢复(五)
增量备份 gpbackup和gprestore工具支持创建追加优化表的增量备份以及从增量备份还原。 只有表被更改时,增量备份才会备份所有指定的堆表和追加优化的表(包括追加优化的,面向列的表)。 例如,如果追加优化表的行已更改&a…...
lenovo联想笔记本ThinkPad P16V Gen 1(21FC,21FD)原装出厂Win11系统
原厂W11系统自带所有驱动、出厂主题壁纸、Office办公软件、联想电脑管家等预装程序 链接:https://pan.baidu.com/s/17dTExDSz-EDN4Qd-PZGJuw?pwdrgl3 提取码:rgl3 所需要工具:32G或以上的U盘 文件格式:ISO 文件大小…...
Django实现音乐网站 ⒃
使用Python Django框架制作一个音乐网站, 本篇主要是歌手详情页-专辑列表、专辑详情-单曲列表开发实现内容。 目录 歌手详情-专辑列表 路由设置 跳转设置 视图方法 模板内容 专辑详情-单曲列表 设置路由 视图处理并返回 模板渲染 分页优化 引入错误类型库…...
【开发问题系列】CSV转Excel
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...
mysql物理备份步骤
原库10.153.88.5,新建数据库实例10.153.88.6,注意/etc/my.cnf配置和88.5一致,测试目的是通过copy数据文件到88.6来恢复数据库。 在数据库10.153.88.5打包数据文件: [mysqlt3-dtpoc-dtpoc-web04 mysql]$ cd /testdata/mysql [mys…...
react使用hook封装一个tab组件
目录 react使用hook封装一个tab组件Tabbar.jsx使用组件效果 react使用hook封装一个tab组件 Tabbar.jsx import PropsTypes from "prop-types"; import React, { useEffect, useState } from react; export default function Tabbar(props) {const { tabData , cur…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
