二叉树题目:根据二叉树创建字符串

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:根据二叉树创建字符串

出处:606. 根据二叉树创建字符串

难度

3 级

题目描述

要求

给你二叉树的根结点 root \texttt{root} root,使用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串,并返回。

省略所有不影响字符串与原始二叉树之间的一对一映射关系的空括号对。

示例

示例 1:

示例 1

输入: root = [1,2,3,4] \texttt{root = [1,2,3,4]} root = [1,2,3,4]
输出: "1(2(4))(3)" \texttt{"1(2(4))(3)"} "1(2(4))(3)"
解释:原始字符串是 "1(2(4)())(3())" \texttt{"1(2(4)())(3())"} "1(2(4)())(3())",但是需要省略所有不必要的空括号对。结果是 "1(2(4))(3)" \texttt{"1(2(4))(3)"} "1(2(4))(3)"

示例 2:

示例 2

输入: root = [1,2,3,null,4] \texttt{root = [1,2,3,null,4]} root = [1,2,3,null,4]
输出: "1(2()(4))(3)" \texttt{"1(2()(4))(3)"} "1(2()(4))(3)"
解释:和第一个示例相似,除了不能省略第一个对括号来中断输入和输出之间的一对一映射关系。

数据范围

  • 树中结点数目在范围 [1, 10 4 ] \texttt{[1, 10}^\texttt{4}\texttt{]} [1, 104]
  • -1000 ≤ Node.val ≤ 1000 \texttt{-1000} \le \texttt{Node.val} \le \texttt{1000} -1000Node.val1000

解法一

思路和算法

这道题要求将二叉树按照前序遍历的顺序转换成字符串。由于二叉树的前序遍历是一个递归的过程,因此将二叉树按照前序遍历的顺序转换成字符串也可以使用递归实现。

递归的终止条件是当前结点为空,此时返回空字符串。其余情况下,首先将当前结点值拼接到字符串中,然后分别判断左子树和右子树是否为空,执行相应的操作。

  • 如果左子树和右子树都为空,则当前结点是叶结点,将字符串返回。

  • 如果左子树不为空且右子树为空,则对左子结点调用递归,将左子树转换成字符串并拼接到当前结点为根结点的子树对应的字符串中,左子树对应的字符串前后需要加上括号。此时不需要将右子树转换成字符串。

  • 如果右子树不为空,则依次对左子结点和右子结点调用递归,将左子树和右子树分别转换成字符串并拼接到当前结点为根结点的子树对应的字符串中,左子树和右子树对应的字符串前后都需要加上括号。此时无论左子树是否为空,都需要将左子树转换成字符串。

代码

class Solution {public String tree2str(TreeNode root) {if (root == null) {return "";}StringBuffer sb = new StringBuffer();sb.append(root.val);if (root.left == null && root.right == null) {return sb.toString();}if (root.right == null) {sb.append('(');sb.append(tree2str(root.left));sb.append(')');} else {sb.append('(');sb.append(tree2str(root.left));sb.append(')');sb.append('(');sb.append(tree2str(root.right));sb.append(')');}return sb.toString();}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次,每个结点转换成字符串的时间都是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是递归调用的栈空间和转换成的字符串空间,递归调用的栈空间取决于二叉树的高度,最坏情况下是 O ( n ) O(n) O(n),字符串空间取决于结点数,是 O ( n ) O(n) O(n)

解法二

思路和算法

也可以使用迭代的方法将二叉树转换成字符串。使用迭代的方法,需要使用栈存储结点。

由于将二叉树转换成字符串需要遵循前序遍历的顺序,因此可以按照前序遍历的方法实现。字符串中,除了每个结点值以外,还需要在正确的位置添加括号。对于左括号,只需要在每个结点值的前面添加左括号即可。更复杂的是另外两种情况:一是当左子结点为空时需要添加空括号对,二是当结点访问结束时如何添加右括号。

对于第一种情况,在访问一个结点之后,如果发现该结点的左子结点为空且右子结点不为空,则需要添加空括号对。

对于第二种情况,需要考虑括号的作用。左括号表示进入更深的一层,右括号表示回到上一层,因此在判断如何添加右括号时,应考虑当前访问的结点和下一个待访问的结点之间的层数之差。为了实现这一点,需要对每个结点维护层数,因此需要使用另一个栈存储每个结点的层数。规定根结点的层数是 0 0 0,对于存在父结点和子结点关系的两个结点,子结点的深度是父结点的深度加 1 1 1

根据前序遍历的迭代实现,每次访问一个结点之后将当前结点移动到其左子结点,直到当前结点为空。此时将一个结点出栈,如果出栈结点的右子结点不为空,则出栈结点的右子结点即为下一个待访问的结点,如果出栈结点的右子结点为空,则继续将一个结点出栈,重复上述操作。因此当前层数(即上一个访问的左子结点的层数)和出栈结点的层数之差即为需要添加的右括号数量,添加右括号的同时将当前层数相应减少,直到当前层数等于出栈结点的层数。

遍历结束之后,层数需要恢复到访问根结点之前。由于根结点的层数是 0 0 0,因此需要添加的右括号数量为当前层数加 1 1 1

添加最后的右括号之后,整个字符串的最外层是一对括号,包围整个二叉树转换成的字符串。由于返回值的要求是没有最外层的一对括号,因此去掉最外层的一对括号即可得到二叉树转换成的字符串。

代码

class Solution {public String tree2str(TreeNode root) {StringBuffer sb = new StringBuffer();Deque<TreeNode> nodeStack = new ArrayDeque<TreeNode>();Deque<Integer> levelStack = new ArrayDeque<Integer>();TreeNode node = root;int level = -1;int rightCount = 0;while (!nodeStack.isEmpty() || node != null) {while (node != null) {level++;sb.append('(');sb.append(node.val);nodeStack.push(node);levelStack.push(level);node = node.left;}TreeNode parent = nodeStack.pop();int parentLevel = levelStack.pop();node = parent.right;if (node != null && parent.left == null) {sb.append("()");rightCount++;}while (level > parentLevel) {sb.append(')');level--;}}while (level > -1) {sb.append(')');level--;}return sb.substring(1, sb.length() - 1);}
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。每个结点都被访问一次,每个结点转换成字符串的时间都是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是二叉树的结点数。空间复杂度主要是栈空间和转换成的字符串空间,栈空间取决于二叉树的高度,最坏情况下是 O ( n ) O(n) O(n),字符串空间取决于结点数,是 O ( n ) O(n) O(n)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/30415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu 安装 nvidia 驱动

ubuntu 安装 nvidia 驱动 初环境与设备查询型号查询对应的驱动版本安装驱动验证驱动安装结果 本篇文章将介绍ubuntu 安装 nvidia 驱动 初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统&#xff1a;ubuntu 设备&#xff1a;Nvidia GeForce RTX 4090 查询型…

Linux C 语言 mosquitto 方式 MQTT 发布消息

1 说明 采用 mosquitto 库&#xff0c;实现对主题发布消息。 其中服务器有做限制&#xff0c;需要对应的 cilent id &#xff0c;cafile 、certfile 、keyfile 等配置 2 开发环境 采用ubuntu 直接编译调试 安装mosquitto 库 sudo apt install libmosquitto-dev sudo apt-ge…

PyTorch 微调终极指南:第 2 部分 — 提高模型准确性

一、说明 如今&#xff0c;在训练深度学习模型时&#xff0c;通过在自己的数据上微调预训练模型来迁移学习已成为首选方法。通过微调这些模型&#xff0c;我们可以利用他们的专业知识并使其适应我们的特定任务&#xff0c;从而节省宝贵的时间和计算资源。本文分为四个部分&…

亿欧智库:2023中国宠物行业新趋势洞察报告(附下载)

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 户外赛道本质上迎合了全球共性需求的增长&#xff0c;从养宠意愿的转化到养宠生活的需求&#xff0c;多层次的需求推动行业发展新趋势 从需求端进行分析&#xff0c;可以将养宠意愿的转化分为三个层…

OSPF 动态路由协议 路由传递

影响OSPF路由选择的因素&#xff1a; 1.OSPF路由的开销值&#xff1a;宽带参考值默认为100. COST1000/接口带宽。此时接口 带宽的值可更改&#xff0c;更改后只改变参考数值&#xff0c;带宽仍然为初始值。 注意&#xff1a;更改COST需要 在路由的入方向&#xff0c;数据的出方…

3分钟了解别人如何用ChatGPT打造独特个人IP(成为网红)的

​想必你也有所察觉&#xff0c;在当前形势下&#xff0c;打造个人IP非常重要。许多有影响力的CEO和网红都在打造自己IP。如果你还没有建立自己的个人IP&#xff0c;那么现在正是开始的时候。而且&#xff0c;相比以前&#xff0c;你甚至都不需要找专业的个人IP顾问了&#xff…

【数据结构OJ题】轮转数组

原题链接&#xff1a;https://leetcode.cn/problems/rotate-array/ 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 1. 方法一&#xff1a;暴力求解&#xff0c;将数组的第一个元素用临时变量tmp存起来&#xff0c;再将数组其他元素往右挪动一步&…

编译iOS系统可用的FFmpeg

在进行编译之前&#xff0c;需要做一些准备工作安装必备文件&#xff1a; 1 安装 gas-preprocessor FFmpeg-iOS-build-script 自动编译脚本需要使用到 gas-preprocessor . 执行 sudo git clone https://github.com/bigsen/gas-preprocessor.git /usr/local/bin/gas sudo c…

ChatGPT会取代搜索引擎吗?BingChat、GoogleBard与ChatGPT区别

目前暂时不会&#xff0c;ChatGPT为代表的聊天机器人很可能会直接集成到搜索中&#xff0c;而不是取代它。微软已经通过Bing Chat和Bing做到了这一点&#xff0c;它将“聊天”选项卡直接放入Bing搜索的菜单中。Google、百度也分别开始尝试通过其AI生成技术将Google Bard、文心一…

创建好的VMware虚拟机如何连接上外网?MobaX和XShell如何连接虚拟机

配置虚拟机网卡 首先点击VMware菜单栏&#xff0c;编辑-虚拟网络编辑器-更改设置 选择VMnet8-NAT设置&#xff0c;并记住子网IP之后有用 记住网关IP 修改实际创建的虚拟机网卡 修改设置&#xff0c;vi /etc/sysconfig/network-scripts/ifcfg-ens32 修改前&#xff1a; 修…

FineBI 人力资源 专题

此处使用FineBI处理人力资源数据&#xff0c;数据来源于HR_database数据文件&#xff0c;将此文件拷贝到安装目录下 然后配置数据库连接 在【公共数据】中新建一个文件夹&#xff0c;并将之前数据库中需要用到的表放入此处&#xff0c;更新数据。显示如下。 这时候首先要建立…

PCI 简易通讯控制器有黄色感叹号

一、问题描述 设备管理器中&#xff0c;其他设备中显示 “PCI 简易通讯控制器”驱动未安装&#xff0c;显示黄色感叹号&#xff1a; 二、原因分析 右键该驱动&#xff0c;查看属性ID&#xff0c;显示为&#xff1a; PCI \ VEN_8086&#xff06;DEV_1C3A&#xff06;SUBSYS…

react-virtualized可视化区域渲染的使用

介绍 github地址&#xff1a;https://github.com/bvaughn/react-virtualized 实例网址&#xff1a;react-virtualized如果体积太大&#xff0c;可以参考用react-window。 使用 安装&#xff1a; yarn add react-virtualized。在项目入口文件index.js中导入样式文件&#xff…

集合工具类 Collections:提升集合操作效率

文章目录 多元素添加&#xff1a;addAll 方法随机置换&#xff1a;shuffle 方法自定义对象排序&#xff1a;sort 方法总结 在Java的集合框架中&#xff0c;Collections 是一个包含了许多操作集合的静态方法的工具类。通过使用 Collections 类提供的方法&#xff0c;我们能够更加…

FineReport 使用汇总(不定期更新)

1&#xff0c;下载地址 免费下载FineReport - FineReport报表官网 这里注意 2&#xff0c;后台统计 sql 还是需要自己写 就会有数据 而直接查询表&#xff0c; 没有数据 不过&#xff0c;可能是我不会用。还需要再研究。

事务,不只ACID | 京东物流技术团队

1. 什么是事务&#xff1f; 应用在运行时可能会发生数据库、硬件的故障&#xff0c;应用与数据库的网络连接断开或多个客户端端并发修改数据导致预期之外的数据覆盖问题&#xff0c;为了提高应用的可靠性和数据的一致性&#xff0c;事务应运而生。 从概念上讲&#xff0c;事务…

用C语言高效地打印杨辉三角

假设杨辉三角的通项公式为a(n)&#xff0c;则打印形式如下&#xff1a; 然而我们知道&#xff0c;它应该是这样的&#xff1a; 三角形两边的值都为1&#xff0c;且每个元素的值都为该元素正上方和其正上方前面的元素的值之和。 为了实现这个代码&#xff0c;我们需要知道每行首…

最新SQLMap进阶技术

点击星标&#xff0c;即时接收最新推文 本文选自《web安全攻防渗透测试实战指南&#xff08;第2版&#xff09;》 五折购买链接&#xff1a;u.jd.com/3ibjeF6 SQLMap进阶&#xff1a;参数讲解 &#xff08;1&#xff09;--level 5&#xff1a;探测等级。 参数“--level 5”指需…

数据库签名的那些事儿

写在前面&#xff0c;关于签名的应用场景 除了我们后端经常使用的接口签名来校验数据这些常见的场景&#xff0c;对于数据安全性要求比较严格的业务来说&#xff0c;大部分落库的核心数据 也都需要签名&#xff0c;为啥? 因为怕数据库的数据被篡改数据或者被攻击了&#xff0c…

vue2.7如何使用vue-i18n

版本&#xff1a; vue&#xff1a;2.7.0 vue-i18n&#xff1a;8.28.2 一、下载 npm i vue-i18n8.28.2二、新建 新建一个文件&#xff0c;例如&#xff1a;lang&#xff0c;项目结构如下&#xff1a; index.js&#xff1a; import Vue from vue import VueI18n from vue-i18n…