python-leetcode 45.二叉树转换为链表

题目:

给定二叉树的根节点root,请将它展开为一个单链表:

展开后的单链表应该使用同样的TreeNode,其中right子指针指向链表中的下一个节点,而左子指针始终为空

展开后的单链表应该与二叉树先序遍历顺序相同


方法一:二叉树的前序遍历 

将二叉树展开为单链表之后,单链表中的节点顺序即为二叉树的前序遍历访问各节点的顺序。因此,可以对二叉树进行前序遍历,获得各节点被访问到的顺序。由于将二叉树展开为链表之后会破坏二叉树的结构,因此在前序遍历结束之后更新每个节点的左右子节点的信息,将二叉树展开为单链表。

通过递归实现前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def flatten(self, root):""":type root: Optional[TreeNode]:rtype: None Do not return anything, modify root in-place instead."""preorderList=[]#创建一个空列表,用于存储二叉树的所有节点def preorderTraversal(root):#递归函数,用于对树进行前序遍历if root: #前序遍历的顺序是:根 -> 左 -> 右。preorderList.append(root)preorderTraversal(root.left)preorderTraversal(root.right)preorderTraversal(root)size=len(preorderList)#二叉树的节点总数for i in range(1,size): #从第二个节点开始,直到最后一个节点。因为链表的第一个节点已经由根节点 root 来表示prev,curr=preorderList[i-1],preorderList[i]#取当前节点 curr 和前一个节点 prevprev.left=None#将 prev 节点的左指针设置为 Noneprev.right=curr #将 prev 节点的右指针指向 curr

通过迭代的方式实现前序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def flatten(self, root):""":type root: Optional[TreeNode]:rtype: None Do not return anything, modify root in-place instead."""preorderList = []  # 初始化一个空列表用于存储二叉树的节点stack = []  # 初始化一个空栈用于存储遍历过程中暂时访问的节点node = root# 前序遍历二叉树while node or stack:while node:preorderList.append(node)  # 将当前节点添加到列表中stack.append(node)  # 将当前节点添加到栈中node = node.left  # 继续遍历左子树node = stack.pop()  # 当左子树遍历结束时,从栈中弹出一个节点,这个节点是待访问的右子节点(即上一个节点的右子树)node = node.right  # 继续访问右子树# 构建链表(右子树按前序遍历顺序连接)size = len(preorderList)for i in range(1, size):  # 从第二个节点开始(因为第一个节点已经是链表的头节点)prev, curr = preorderList[i - 1], preorderList[i]prev.left = None  # 清空左子树prev.right = curr  # 将前一个节点的右指针指向当前节点

时间复杂度:O(n),其中 n 是二叉树的节点数。前序遍历的时间复杂度是 O(n),前序遍历之后,需要对每个节点更新左右子节点的信息,时间复杂度也是 O(n)。

空间复杂度:O(n),其中 n 是二叉树的节点数。空间复杂度取决于栈(递归调用栈或者迭代中显性使用的栈)和存储前序遍历结果的列表的大小,栈内的元素个数不会超过 n,前序遍历列表中的元素个数是 n


方法三:寻找前驱节点

前序遍历访问各节点的顺序是根节点、左子树、右子树。如果一个节点的左子节点为空,则该节点不需要进行展开操作。。如果一个节点的左子节点不为空,则该节点的左子树中的最后一个节点被访问之后,该节点的右子节点被访问。该节点的左子树中最后一个被访问的节点是左子树中的最右边的节点,也是该节点的前驱节点。因此,问题转化成寻找当前节点的前驱节点。

对于当前节点,如果其左子节点不为空,则在其左子树中找到最右边的节点,作为前驱节点,,将当前节点的右子节点赋给前驱节点的右子节点,然后将当前节点的左子节点赋给当前节点的右子节点,并将当前节点的左子节点设为空。对当前节点处理结束后,继续处理链表中的下一个节点,直到所有节点都处理结束。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):def flatten(self, root):""":type root: Optional[TreeNode]:rtype: None Do not return anything, modify root in-place instead."""curr=rootwhile curr:if curr.left:predecessor=nxt=curr.left#用来找到左子树中最右的节点while predecessor.right:#找到左子树中的最右节点predecessor=predecessor.right #向右移动,寻找最右边的节点predecessor.right=curr.right#找到左子树中的最右节点后,将当前节点的右子树连接到左子树的最右节点上curr.left=None     #当前节点的左子树被置为curr.right=nxt#将当前节点的右指针指向左子树的根节点curr=curr.right #使curr移动到下一个节点(即当前右子树的第一个节点),继续遍历   

时间复杂度:O(n)其中 n 是二叉树的节点数。展开为单链表的过程中,需要对每个节点访问一次,在寻找前驱节点的过程中,每个节点最多被额外访问一次

空间复杂度:O(1)

源自力扣官方题解
 

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

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

相关文章

【leetcode hot 100 15】三数之和

一、两数之和的扩展 class Solution {public List<List<Integer>> threeSum(int[] nums) {// 将得到的结果存入Set中&#xff0c;保证不重复Set<List<Integer>> set new HashSet<>();// 模拟两数之和&#xff0c;作为第一个循环中的内容for(in…

设备健康管理系统在制造业的深度应用探索

引言 在制造业的数字化转型浪潮中&#xff0c;设备健康管理系统正逐渐成为企业提升竞争力的关键利器。随着工业 4.0 和智能制造概念的不断深入&#xff0c;制造业对设备的高效、稳定运行提出了更高要求。设备健康管理系统借助先进的传感器技术、物联网&#xff08;IoT&#xf…

HTTPS 与 HTTP 的区别在哪?

HTTP与HTTPS作为互联网数据传输的核心协议&#xff0c;其通信机制与安全特性深刻影响着现代网络应用的可靠性与用户体验。本文将解析两者的通信流程、安全机制及核心差异。 一、HTTP的通信机制 先来看看HTTP是什么吧。 HTTP基于TCP/IP协议栈&#xff0c;采用经典客户端-服务…

为什么要将PDF转换为CSV?CSV是Excel吗?

在企业和数据管理的日常工作中&#xff0c;PDF文件和CSV文件承担着各自的任务。PDF通常用于传输和展示静态的文档&#xff0c;而CSV因其简洁、易操作的特性&#xff0c;广泛应用于数据存储和交换。如果需要从PDF中提取、分析或处理数据&#xff0c;转换为CSV格式可能是一个高效…

【JAVAEE】多线程

【JAVAEE】多线程 一、进程1.1 进程的定义1.2 进程和线程的联系 二、线程2.1 JConsole工具2.2 创建线程2.2.1 Thread类&#xff0c;start&#xff08;&#xff09;&#xff0c;run&#xff08;&#xff09;2.2.2 继承Thread类2.2.3 实现Runnable接口2.2.4 匿名内部类2.2.5 使用…

手机打电话时如何识别对方按下的DTMF按键的字符-安卓AI电话机器人

手机打电话时如何识别对方按下的DTMF按键的字符 --安卓AI电话机器人 一、前言 前面的篇章中&#xff0c;使用蓝牙电话拦截手机通话的声音&#xff0c;并对数据加工&#xff0c;这个功能出来也有一段时间了。前段时间有试用的用户咨询说&#xff1a;有没有办法在手机上&#xff…

【Go】十八、http 调用服务的编写

http接口框架的搭建 这个http接口框架的搭建参考之前的全量搭建&#xff0c;这里是快速搭建的模式&#xff1a; 直接对已有的http模块进行复制修改&#xff0c;主要修改点在于 proto部分与api、router 部分&#xff0c;剩余的要针对进行修改模块名称。 接口的具体编写 在 a…

WiseFlow本地搭建实录---保姆教程

今天从零开始搭建了Wiseflow的本地环境搭建&#xff0c;目前使用的都是免费的API&#xff0c;我建议大家可以一起尝试一下搭建自己的关键信息的数据库&#xff0c;我是windows的环境&#xff0c;但是其他的应该也差不多&#xff0c;踩了很多坑&#xff0c;希望这篇文章能帮大家…

数的计算(蓝桥云课)

题目描述 输入一个自然数 n (n≤1000)n (n≤1000)&#xff0c;我们对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该自然数不能超过原数的一半; 加上数后,继续按此规则进行处理,直到不能再加自然数为止。 问总共可以产生多少个数。 输入描述 输…

知识库功能测试难点

图表交互功能测试难点 知识库图表类型多&#xff0c;每种图表交互功能不同。像柱状图&#xff0c;可能有点击柱子查看详细数据、鼠标悬停显示数据提示等交互&#xff1b;折线图除了这些&#xff0c;还可能支持缩放查看不同时间段数据。多种交互操作在不同图表间存在差异&#x…

【人工智能】数据挖掘与应用题库(201-300)

1、在LetNet5网络中,卷积核的大小是? 答案:5*5 2、LeNet5网络参数的数量约为? 答案:6万 3、AlexNet与LeNet5相比,使用了哪些机制来改进模型的训练过程? 答案: 数据增广Dropout抑制过拟合ReLU激活函数CUDA加速神经网络训练4、VGGNet使用的卷积核的大小是? 答案:…

web安全渗透测试 APP安全渗透漏洞测试详情

前言 小小白承包了一块20亩的土地&#xff0c;依山傍水&#xff0c;风水不错。听朋友说去年玉米大卖&#xff0c;他也想尝尝甜头&#xff0c;也就种上了玉米。 看着玉米茁壮成长&#xff0c;别提小小白心里多开心&#xff0c;心里盘算着玉米大买后&#xff0c;吃香喝辣的富贵…

CSS处理内容溢出

<!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>处理内容溢出</title><style>#d1{wid…

拉丁超立方采样(Latin Hypercube Sampling)技术详解及实现

拉丁超立方采样(Latin Hypercube Sampling)技术详解 拉丁超立方采样(Latin Hypercube Sampling)技术详解1. 引言2. 拉丁超立方采样原理3. 数学公式描述4. Python代码实现代码解析5. 应用场景与优势6. 在化工中的应用6.1 工艺参数优化6.2 不确定性量化与风险评估6.3 实验设计…

docker-compose部署onlyoffice8.3.0并支持ssl,且支持通过nginx代理,关闭JWT配置

编写docker-compose文件 mkdir -p /data/onlyoffice && echo "version: 3services:onlyoffice:container_name: OnlyOfficeimage: onlyoffice/documentserver:8.3.0restart: alwaysports:- 8088:80- 64431:443environment:TZ: Asia/ShanghaiJWT_ENABLED: falsevol…

Sliding Window Attention(滑动窗口注意力)解析: Pytorch实现并结合全局注意力(Global Attention )

Sliding Window Attention&#xff08;滑动窗口注意力&#xff09;解析 Sliding Window Attention&#xff08;滑动窗口注意力&#xff09; 是 Longformer (来源&#xff1a;https://arxiv.org/pdf/2004.05150)提出的 稀疏注意力机制&#xff0c;旨在解决 标准 Transformer 计算…

【运维】内网服务器借助通过某台可上外网的服务器实现公网访问

背景&#xff1a; 内网服务器无法连接公网,但是办公电脑可以连接内网服务器又可以连接公网。 安装软件 1、frp 2、ccproxy 配置 1、内网服务器 # 内网服务器启动frp服务配置文件参考vi frps.ini# frps.ini [common] bind_port 7000# 备注: bind_port端口可以随意配置。配置完…

flask 是如何分发请求的?

这篇博客会涉及一些 WSGI 的知识&#xff0c;不了解的可以看这篇博客&#xff0c;简单了解一下。 Python 的 WSGI 简单入门 一、请求在 flask 中的处理过程 我们先来看一下 werkzeug.routing 包下 Map 和 Rule 方法的使用&#xff0c;这里给出一个官方的示例&#xff08;我进…

怎么获取免费的 GPU 资源完成大语言模型(LLM)实验

怎么获取免费的 GPU 资源完成大语言模型(LLM)实验 目录 怎么获取免费的 GPU 资源完成大语言模型(LLM)实验在线平台类Google ColabKaggle NotebooksHugging Face Spaces百度飞桨 AI Studio在线平台类 Google Colab 特点:由 Google 提供的基于云端的 Jupyter 笔记本环境,提…

Python开发Django面试题及参考答案

目录 Django 的请求生命周期是怎样的? Django 的 MTV 架构中的各个组件分别是什么? Django 的 URL 路由是如何工作的? Django 的视图函数和视图类有什么区别? Django 的模板系统是如何渲染 HTML 的? Django 的 ORM 是如何工作的? Django 的中间件是什么?它的作用是…