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

文章目录

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

题目

标题和出处

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

出处: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.rhkb.cn/news/84709.html

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

相关文章

【广州华锐视点】AR电力职业技能培训系统让技能学习更“智慧”

随着科技的发展&#xff0c;教育方式也在不断地进步和创新。其中&#xff0c;增强现实(AR)技术的出现&#xff0c;为教育领域带来了全新的可能。AR电力职业技能培训系统就是这种创新教学方法的完美实践&#xff0c;它将虚拟与现实相结合&#xff0c;为学生提供了一个沉浸式的学…

Token 失效退出至登录页面

1. 在登录页面&#xff0c;调用登录的接口后&#xff0c;直接写上当前时间&#xff0c;保存在本地 代码&#xff1a; // 点击登录login(form) {this.$refs[form].validate((valid) > {if (valid) {this.$API.Login(this.form).then((res) > {// console.log(res, "1…

AIRIOT出席IOTE生态行·北京物联网应用交流大会

8月8日&#xff0c;由物联传媒、IOTE物联展、AIoT库、AIoT星图研究院联合主办的IOTE生态行北京物联网应用交流大会圆满结束&#xff0c;超300位业界同行同台交流。 航天科技控股集团股份有限公司受邀参会&#xff0c;旗下AIRIOT物联网平台产品负责人段丽娜发表演讲&#xff0c;…

JVM 性能优化思路

点击下方关注我&#xff0c;然后右上角点击...“设为星标”&#xff0c;就能第一时间收到更新推送啦~~~ 一般在系统出现问题的时候&#xff0c;我们会考虑对 JVM 进行性能优化。优化思路就是根据问题的情况&#xff0c;结合工具进行问题排查&#xff0c;针对排查出来的可能问题…

uniapp软键盘谈起遮住输入框和头部被顶起的问题解决

推荐&#xff1a; pages.json中配置如下可解决头部被顶起和表单被遮住的问题。 { "path": "pages/debug/protocol/tagWord", "style": { "app-plus": { "soft…

Alpine Ridge控制器使其具备多种使用模式 - 英特尔发布雷电3接口:竟和USB Type-C统一了

同时又因为这建立在Type-C的基础上&#xff0c;雷电3也将利用现有的标准Type-C线缆引入有源支持。当使用Type-C的线缆时&#xff0c;雷电的速度就降到了20Gbps全双工——这与普通的Type-C的带宽相同——这是为了成本牺牲了一些带宽。可以比较一下&#xff0c;Type-C线的成本只有…

asyncio是什么?

如果把进程比作从A处到B处去这件事&#xff0c;那么线程就是可供选择的多条道路&#xff0c;协程就是道路上特殊路段&#xff08;类似限速&#xff0c;一整条道路都是特殊路段的话&#xff0c;就是全部由协程实现&#xff09; 例图如下&#xff1a; 1. 什么是协程&#xff08…

winform 使用CommonOpenFileDialog选择文件夹或文件

选择文件夹 /// <summary> /// 选择文件夹 /// </summary> public void SelectFolder() {CommonOpenFileDialog dialog new CommonOpenFileDialog("请选择一个文件夹");dialog.IsFolderPicker true; //选择文件还是文件夹&#xff08;true:选择文件夹…

undefined reference to `dlopen‘ ‘SSL_library_init‘ `X509_certificate_type‘

使用Crow的时候需要注意crow依赖asio依赖OpenSSL&#xff0c;asio要求1.22以上版本&#xff0c;我使用的是1.26.0&#xff1b; 这个版本的asio要求OpenSSL是1.0.2&#xff0c;其他版本我得机器上编不过&#xff0c;ubuntu上默认带的OpenSSL是1.1.1; 所以我下载了OPENSSL1.2.0重…

android APP内存优化

Android为每个应用分配多少内存 Android出厂后&#xff0c;java虚拟机对单个应用的最大内存分配就确定下来了&#xff0c;超出这个值就会OOM。这个属性值是定义在/system/build.prop文件中. 例如&#xff0c;如下参数 dalvik.vm.heapstartsize8m #起始分配内存 dalvik.vm.…

qt在vs中编译出现link2001时,不会生成moc文件了

现象&#xff1a; 解决方法&#xff1a; 在对应头文件-属性-配置属性-常规-项类型-改为Qt Meta-Object Compiler (moc) 即可。 有时候不知道啥原因头文件类型变成普通C头文件

Pyinstaller 打包 django 项目如何将命令行参数加入?

起因 Pyinstaller 打包 django 项目&#xff0c;打包成 manage.exe 后用命令行 cmd manage.exe runserver 0.0.0.0:8001 --noreload 来运行感觉很不方便。 希望能够直接把命令行参数也打包进去&#xff0c;直接运行 exe 。我走了些弯路&#xff0c;但最终实现了。 弯路 我看…

Vue组件的嵌套关系;父组件传递子组件props;子组件传递给父组件$emit;自定义事件;案例

目录 1_Vue组件的嵌套关系1.1_认识组件的嵌套1.2_组件的拆分1.3_组件的通信 2_父组件传递子组件props2.1_父子组件之间通信的方式2.2_父组件传递给子组件2.3_Props的对象用法 3_子组件传递给父组件$emit4_自定义事件(了解)5_小案例6_补充 1_Vue组件的嵌套关系 1.1_认识组件的嵌…

【C++】set 和 map 简单了解使用

文章目录 关联式容器set 和 multisetmap 和 multimap 关联式容器 set 和 multiset map 和 multimap

WebDAV之π-Disk派盘+Joplin

Joplin是一个优秀的开源笔记,可以组织到笔记本中的大量笔记和文本编辑器中进行复制,标记和修改。支持Evernote的笔记直接导入到Joplin应用程序中。Joplin还支持各种云服务同步,包括Dropbox、OneDrive、WebDAV或文件系统,方便对其进行检查、备份和移动。该应用程序可用于Win…

为什么DNS协议运行在UDP之上?

DNS (Domain Name System) 运行在 UDP (User Datagram Protocol) 上主要是出于以下原因&#xff1a; 简单性和效率&#xff1a;UDP 是无连接的&#xff0c;这意味着与建立和维护 TCP 连接相比&#xff0c;UDP 有更少的开销。当 DNS 查询被发送时&#xff0c;它只需要一个小的请…

关于@JSONField的使用

1.此注解来自jar包com.alibaba.fastjson 今天分享一个有意思的事情。这个注解作用与类的属性上&#xff0c;如下&#xff1a; ApiModelProperty(value"开始时间,格式:yyyy-MM-dd",required true) JSONField(name"start_date",ordinal 1) private String…

18 Java并发机制的底层实现原理_volatile实现原理

Java并发机制的底层实现原理_volatile实现原理 Java并发机制的底层实现原理volatile 关键字volatile的两条实现原则&#xff08;Lock前缀的作用&#xff09; Java并发机制的底层实现原理 Java代码在编译后会变成Java字节码&#xff0c;字节码被类加载器加载到JVM里&#xff0c;…

将本地项目上传至gitee的详细步骤

将本地项目上传至gitee的详细步骤 1.在gitee上创建以自己项目名称命名的空项目2.进入想上传的项目的文件夹&#xff0c;然后右键点击3. 初始化本地环境&#xff0c;把该项目变成可被git管理的仓库4.添加该项目下的所有文件5.使用如下命令将文件添加到仓库中去6.将本地代码库与远…

项目实战 — 消息队列(7){虚拟主机设计(1)}

目录 一、什么是虚拟主机 二、编写虚拟主机代码 &#x1f345; 1、准备工作 &#x1f345; 2、实现exchange相关操作 &#x1f384;实现创建交换机exchangeDeclare &#x1f384; 实现 删除交换机exchangeDelete &#x1f345; 3、实现queue相关操作 &#x1f384;实现…