[模版总结] - 树的基本算法3 - 结构转化

二叉树结构转化

  • 通常将二叉树根据某些要求进行结构重构,比如线性结构转化(链表,数组),序列化等。

常见题型

注:这类题目最基本的解题思路是利用递归分治 (也可以使用迭代方法),在构建树结构的时候,我们通常会使用前序遍历的思路自上而下,进行建树,每一次递归中,得到左右子树的值进行连接。

链表类

Leetcode 114 - Flatten Binary Tree to LinkedList

LeetCode 426 - Convert BST to Sorted Doubly Linked List

线性数组或字符类

Leetcode 297. 序列化和反序列化二叉树

Leetcode 106. Construct Binary Tree from Inorder and Postorder Traversal

Leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal

Leetcode 536. Construct Binary Tree from String

Leetcode 606. Construct String from Binary Tree

Leetcode 889. Construct Binary Tree from Preorder and Postorder Traversal

二叉搜索树

Leetcode 449. Serialize and Deserialize BST

题目思路

Leetcode 114 - Flatten Binary Tree to LinkedList

将二叉树以前序遍历的顺序转化成连接结构,要求in-place即不占用额外空间存储新的链表结构。基本思路是递归分治,这里我们使用后序遍历的思路,先拿到左右结点然后转化成链表结构,在每一次递归中:

  1. 拿到左右子结点
  2. 如果左子树为空则直接返回右子树
  3. 如果左子树不为空,将左子树的最右边的结点与当前节点右子树连接,然后将当前节点右边连接到该左子树,然后将当前节点左子树置空。

代码如下:

class Solution {public void flatten(TreeNode root) {dfs(root);}private void dfs(TreeNode root) {if (root==null) return;if (root.left==null && root.right==null) return;dfs(root.left);dfs(root.right);if (root.left==null) return;else {TreeNode dum = root.left;while (dum.right!=null) {dum = dum.right;}dum.right = root.right;root.right = root.left;root.left = null;}}
}

Leetcode 606. Construct String from Binary Tree

二叉树序列化问题,根据二叉树前序遍历顺序将各节点按照继承关系打印出来

例子:[1,2,3,4] -> "1(2(4))(3)"

二叉树序列化,通常思路就是前序遍历依次打印各个节点,按照分治的思路,我们在每一次递归任务中,需要做以下步骤:

  1. 打印当前节点
  2. 打印左括号
  3. 遍历左子树
  4. 打印右括号
  5. 判断右子树是否为空,如果不为空重复 2,3(打印右子树),4。

代码如下:

时间复杂度:O(N) ; 空间复杂度:O(h) , h代表递归深度。

class Solution {StringBuilder str = new StringBuilder();public String tree2str(TreeNode root) {dfs(root);return str.toString();}private void dfs(TreeNode root) {if (root==null) return;str.append(root.val+"");if (root.left==null && root.right==null) return;str.append('(');dfs(root.left);str.append(')');// skip if right == nullif (root.right!=null) {str.append('(');dfs(root.right);str.append(')');}}
}

 

Leetcode 536. Construct Binary Tree from String

这道题目则是上面LC.606的反序列化,通过给定序列化字符串构造原始的树结构,由于序列化后可以通过"()" 来判断节点的父子关系,这道题思路有一些类似Leetcode基础计算器或者表达式计算的问题,我们需要维护一个栈结构,在遍历字符串过程中:

  1. 如果遇到左括号,继续循环
  2. 如果遇到数字或者负号,读取数字位,创建结点并加入Stack中
  3. 如果遇到右括号,即需要开始处理结点父子关系,将最近结点pop出来,pop后栈中最顶上的结点一定是pop出结点的父亲结点,将当前节点连接到该父亲结点上,左优先如果左边不为空则连接到右子树。

代码如下:

时间复杂度:O(N) ; 空间复杂度:O(h) , h代表递归深度。

class Solution {public TreeNode str2tree(String s) {if (s==null || s.length()==0) return null;Stack<TreeNode> stk = new Stack<>();for (int i=0; i<s.length();) {if (s.charAt(i)=='(') {i++;continue;} else if (s.charAt(i)==')') {if (!stk.isEmpty()) {TreeNode node = stk.pop();TreeNode parent = stk.peek();if (parent.left==null) parent.left = node;else parent.right = node;}i++;} else {String num = "";while (i<s.length() && ((s.charAt(i)>='0' && s.charAt(i)<='9') || s.charAt(i)=='-')) {num+=s.charAt(i);i++;}TreeNode node = new TreeNode(Integer.parseInt(num));stk.push(node);}}return stk.pop();}
}

Leetcode 297. 序列化和反序列化二叉树

上面两道题目的合并版,比起使用上述括号形式进行序列化编码,这道题目我们可以对于序列化的格式进行简化,对于缺失的左右叶子结点我们用NULL来表示,每一个结点以逗号隔开。

对于反序列化的步骤,由于序列化是以前序遍历的顺序,所以反序列化也利用前序遍历的顺序,每一次递归过程中进行如下操作:

  1. 根据当前遍历的结点创建二叉树结点,并从列表中移除该结点
  2. 向下遍历左右子树,得到左右子树
  3. 将当前节点连接到左右子树,并返回当前节点

前序遍历的特性是根-左-右,是比较适合构建二叉树这类问题

代码如下:

public class Codec {StringBuilder str;// Encodes a tree to a single string.public String serialize(TreeNode root) {str = new StringBuilder();helper(root);return str.toString().substring(0, str.length()-1);}private void helper(TreeNode root) {if (root==null) {str.append("null,");return;}str.append(root.val+",");helper(root.left);helper(root.right);}// Decodes your encoded data to tree.public TreeNode deserialize(String data) {List<String> nodes = new LinkedList<String>(Arrays.asList(data.split(",")));return deshelper(nodes);}private TreeNode deshelper(List<String> nodes) {if (nodes==null || nodes.size()==0) return null;if (nodes.get(0).equals("null")) {nodes.remove(0);return null;}TreeNode curr = new TreeNode(Integer.parseInt(nodes.get(0)));nodes.remove(0);curr.left = deshelper(nodes);curr.right = deshelper(nodes);return curr;}
}

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

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

相关文章

春秋云境靶场CVE-2022-28512漏洞复现(sql手工注入)

文章目录 前言一、CVE-2022-28512靶场简述二、找注入点三、CVE-2022-28512漏洞复现1、判断注入点2、爆显位个数3、爆显位位置4 、爆数据库名5、爆数据库表名6、爆数据库列名7、爆数据库数据 总结 前言 此文章只用于学习和反思巩固sql注入知识&#xff0c;禁止用于做非法攻击。…

前置语音群呼与语音机器人群呼哪个更好

最近通过观察自己接到的营销电话&#xff0c;通过语音机器人外呼的量应该有所下降。同时和客户交流获取到的信息&#xff0c;也是和这个情况类似&#xff0c;很多AI机器人群呼的量转向了OKCC前置语音群呼。询问原因&#xff0c;说是前置语音群呼转化更快&#xff0c;AI机器人群…

通过汇编理解cortex-m3:第0章

第0章&#xff1a;准备工作 基本想法&#xff1a;利用汇编和gdb调试&#xff0c;来学习cortex-m3汇编指令&#xff0c;以及一些寄存器的功能。 软件和硬件&#xff1a; 硬件&#xff1a;韦东山瑞士军刀中的最小核心板&#xff08;STM32F103C8T6&#xff09; STLINK-V2&#…

力扣刷题-二叉树-二叉树最小深度

给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。&#xff08;注意题意&#xff09; 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#x…

【数据结构(二)】队列(2)

文章目录 1. 队列的应用场景和介绍1.1. 队列的一个使用场景1.2. 队列介绍 2. 数组模拟队列2.1. 思路分析2.2. 代码实现 3. 数组模拟环形队列3.1. 思路分析3.2. 代码实现 1. 队列的应用场景和介绍 1.1. 队列的一个使用场景 银行排队的案例&#xff1a; 1.2. 队列介绍 队列是一…

基于STC12C5A60S2系列1T 8051单片的IIC总线器件数模芯片PCF8591实现数模转换应用

基于STC12C5A60S2系列1T 8051单片的IIC总线器件数模芯片PCF8591实现数模转换应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍IIC总线器件数模芯片PCF8591介绍通过按…

前缀和(c++,超详细,含二维)

前缀和与差分 当给定一段整数序列a1,a2,a3,a4,a5…an; 每次让我们求一段区间的和&#xff0c;正常做法是for循环遍历区间起始点到结束点&#xff0c;进行求和计算&#xff0c;但是当询问次数很多并且区间很长的时候 比如&#xff0c;10^5 个询问和10^6区间长度&#xff0c;相…

基于机器学习的居民消费影响因子分析预测

项目视频讲解: 基于机器学习的居民消费影响因子分析预测_哔哩哔哩_bilibili 主要工作内容: 完整代码: import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import missingno as msno import warnings warnings.filterwarnin…

emq Neuron工业协议采集使用

emq Neuron工业协议采集使用 Neuron 简介 EMQ X Neuron 是运行在各类物联网边缘网关硬件上的工业协议商业化网关软件&#xff0c;支持一站式接入和解析数十种工业协议&#xff0c;并转换成 MQTT 协议接入工业物联网平台。用户可以通过基于 Web 的管理控制台可以实现在线的网关…

IDEA调用接口超时,但Postman可成功调用接口

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

消息中间的应用场景

1、异步处理 比如用户在电商网站下单&#xff0c;下单完成后会给用户推送短信或邮件&#xff0c;发短信和邮件的过程就可以异步完成。因为下单付款是核心业务&#xff0c;发邮件和短信并不属于核心功能&#xff0c;并且可能耗时较长&#xff0c;所以针对这种业务场景可以选择先…

OpenCV快速入门:直方图、掩膜、模板匹配和霍夫检测

文章目录 前言一、直方图基础1.1 直方图的概念和作用1.2 使用OpenCV生成直方图1.3 直方图归一化1.3.1 直方图归一化原理1.3.2 直方图归一化公式1.3.3 直方图归一化代码示例1.3.4 OpenCV内置方法&#xff1a;normalize()1.3.4.1 normalize()方法介绍1.3.4.2 normalize()方法参数…

JUnit 单元自动化

一、Junit 是什么&#xff1f; Junit 是 Java 中用于单元测试的框架。使用 Junit 能让我们快速高效的完成单元测试。 自动化测试&#xff1a;JUnit提供了自动化测试的能力&#xff0c;开发人员可以编写一次测试用例&#xff0c;然后通过简单的命令或集成到持续集成工具中进行…

TDengine Restful Authorization 自定义Token

Restful 接口是 TDengine 最常用的接口&#xff0c;仅次于 JDBC。TDengine 支持 HTTP 和 HTTPS&#xff0c;但通常情况下&#xff0c;大家不想搞证书&#xff0c;又在内网环境中&#xff0c;采用 HTTP 方式比较多。但 HTTP 是明文传输&#xff0c;只要抓个包就知道账号密码了。…

MySQL InnoDB 引擎底层解析(一)

6. InnoDB 引擎底层解析 MySQL 对于我们来说还是一个黑盒&#xff0c;我们只负责使用客户端发送请求并等待服务器返回结果&#xff0c;表中的数据到底存到了哪里&#xff1f;以什么格式存放的&#xff1f;MySQL 是以什么方式来访问的这些数据&#xff1f;这些问题我们统统不知…

AnyTXT Searcher:本地文件内容搜索神器如何搭建与远程访问

文章目录 前言1. AnyTXT Searcher1.1 下载安装AnyTXT Searcher 2. 下载安装注册cpolar3. AnyTXT Searcher设置和操作3.1 AnyTXT结合cpolar—公网访问搜索神器3.2 公网访问测试 4. 固定连接公网地址 前言 你是否遇到过这种情况&#xff0c;异地办公或者不在公司&#xff0c;想找…

iOS_折叠展开 FoldTextView

1. 显示效果 Test1&#xff1a;直接使用&#xff1a; Test2&#xff1a;在 cell 里使用&#xff1a; 2. 使用 2.1 直接使用 // 1.1 init view private lazy var mooFoldTextView: MOOFoldTextView {let view MOOFoldTextView(frame: .zero)view.backgroundColor .cyanvie…

Redis字典实现

前言 字典又称符号表&#xff0c;关联数组或者映射(map)。是一种保存键值对的抽象数据结构。在字典中一个键和一个值进行关联。这些关联的值被称为键值对。 字典中每一个键都是独一无二的&#xff0c;没有重复的。我们可以通过键来查找值&#xff0c;更新值或者删除整个键值对等…

如何定位el-tree中的树节点当父元素滚动时如何定位子元素

使用到的方法 Element 接口的 scrollIntoView() 方法会滚动元素的父容器&#xff0c;使被调用 scrollIntoView() 的元素对用户可见。 参数 alignToTop可选 一个布尔值&#xff1a; 如果为 true&#xff0c;元素的顶端将和其所在滚动区的可视区域的顶端对齐。相应的 scrollIntoV…

算法学习 day26

第二十六天 最大子数组和 53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 动态规划问题 class Solution {public int maxSubArray(int[] nums) {int len nums.length;int[] dp new int[len];dp[0] nums[0];int res dp[0];for(int i 1; i < len; i){dp[i] …