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.rhkb.cn/news/25564.html

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

相关文章

vue3.2 + vxe-table4.x 实现多层级结构的 合并、 展开、收起 功能

<template><div style"padding: 20px"><vxe-table border :data"list" :height"800" :span-method"rowspanMethod"><vxe-column title"一级类目" field"category1"><template #defaul…

C++ Primer 成员访问运算符

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

Linux:Shell环境变量与命令行参数

目录 Shell的变量功能 什么是变量 变数的可变性与方便性 影响bash环境操作的变量 脚本程序设计&#xff08;shell script&#xff09;的好帮手 变量的使用&#xff1a;echo 变量的使用&#xff1a;HOME 环境变量相关命令 获取环境变量 环境变量和本地变量 命令行…

ollama和open-webui部署ds

博客地址&#xff1a; ollama和open-webui部署ds 引言 最近&#xff0c;deepseek是越来越火&#xff0c;我也趁着这个机会做了下私有化部署&#xff0c;我这边使用的ollama和 open-webui实现的web版本 ollama 简介 Ollama 是一个开源的工具&#xff0c;专门用于简化机器学…

SpringBoot接口自动化测试实战:从OpenAPI到压力测试全解析

引言&#xff1a;接口测试的必要性 在微服务架构盛行的今天&#xff0c;SpringBoot项目的接口质量直接影响着系统稳定性。本文将分享如何通过自动化工具链实现接口的功能验证与性能压测&#xff0c;使用OpenAPI规范打通测试全流程&#xff0c;让您的接口质量保障体系更加完备。…

Spring Boot 项目开发流程全解析

目录 引言 一、开发环境准备 二、创建项目 三、项目结构 四、开发业务逻辑 1.创建实体类&#xff1a; 2.创建数据访问层&#xff08;DAO&#xff09;&#xff1a; 3.创建服务层&#xff08;Service&#xff09;&#xff1a; 4.创建控制器层&#xff08;Controller&…

RabbitMQ 集群部署方案

RabbitMQ 一、安装 RabbitMQ 二、更改配置文件 三、配置集群 四、测试 环境准备&#xff1a;三台服务器&#xff0c;系统是 CentOS7 IP地址分别是&#xff1a; rabbitmq1&#xff1a;192.168.152.71rabbitmq2&#xff1a;192.168.152.72rabbitmq3&#xff1a;192.168.152.…

SocketTool、串口调试助手、MQTT中间件基础

目录 一、SocketTool 二、串口通信 三、MQTT中间件 一、SocketTool 1、TCP 通信测试&#xff1a; 1&#xff09;创建 TCP Server 2&#xff09;创建 TCP Client 连接 Socket 4&#xff09;数据收发 在TCP Server发送数据12345 在 TCP Client 端的 Socket 即可收到数据12…

LSTM长短期记忆网络-原理分析

1 简介 概念 LSTM&#xff08;Long Short-Term Memory&#xff09;也称为长短期记忆网络&#xff0c;是一种改进的循环神经网络&#xff08;RNN&#xff09;&#xff0c;专门设计用于解决传统RNN的梯度消失问题和长程依赖问题。LSTM通过引入门机制和细胞状态&#xff0c;能够更…

一文了解:部署 Deepseek 各版本的硬件要求

很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求&#xff0c;最近自己实践了一部分&#xff0c;部分信息是通过各渠道收集整理&#xff0c;so 仅供参考。 言归正转&#xff0c;大家都知道&#xff0c;DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…

IP-----动态路由OSPF

这只是IP的其中一块内容&#xff0c;IP还有更多内容可以查看IP专栏&#xff0c;前一章内容为GRE和MGRE &#xff0c;可通过以下路径查看IP-------GRE和MGRE-CSDN博客,欢迎指正 注意&#xff01;&#xff01;&#xff01;本部分内容较多所以分成了两部分在下一章 5.动态路由OS…

ClkLog里程碑:荣获2024上海开源技术应用创新竞赛三等奖

2024年10月&#xff0c;ClkLog团队参加了由上海计算机软件技术开发中心、上海开源信息技术协会联合承办的2024上海数智融合“智慧工匠”选树、“领军先锋”评选活动——开源技术应用创新竞赛。我们不仅成功晋级决赛&#xff0c;还荣获了三等奖&#xff01;这一成就不仅是对ClkL…

计算机毕业设计Python+DeepSeek-R1大模型考研院校推荐系统 考研分数线预测 考研推荐系统 考研(源码+文档+PPT+讲解)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

NFC拉起微信小程序申请URL scheme 汇总

NFC拉起微信小程序&#xff0c;需要在微信小程序开发里边申请 URL scheme &#xff0c;审核通过后才可以使用NFC标签碰一碰拉起微信小程序 有不少人被难住了&#xff0c;从微信小程序开发社区汇总了以下信息&#xff0c;供大家参考 第一&#xff0c;NFC标签打开小程序 https://…

DeepSeek推出DeepEP:首个开源EP通信库,让MoE模型训练与推理起飞!

今天&#xff0c;DeepSeek 在继 FlashMLA 之后&#xff0c;推出了第二个 OpenSourceWeek 开源项目——DeepEP。 作为首个专为MoE&#xff08;Mixture-of-Experts&#xff09;训练与推理设计的开源 EP 通信库&#xff0c;DeepEP 在EP&#xff08;Expert Parallelism&#xff09…

【数据结构】 最大最小堆实现优先队列 python

堆的定义 堆&#xff08;Heap&#xff09;是一种特殊的完全二叉树结构&#xff0c;通常分为最大堆和最小堆两种类型。 在最大堆中&#xff0c;父节点的值总是大于或等于其子节点的值&#xff1b; 而在最小堆中&#xff0c;父节点的值总是小于或等于其子节点的值。 堆常用于实…

重新审视 ChatGPT 和 Elasticsearch:第 2 部分 - UI 保持不变

作者&#xff1a;来自 Elastic Jeff Vestal 本博客在第 1 部分的基础上进行了扩展&#xff0c;介绍了基于 RAG 的搜索系统的功能齐全的 Web UI。最后&#xff0c;你将拥有一个将检索、搜索和生成过程结合在一起的工作界面&#xff0c;同时使事情易于调整和探索。 不想读完整个内…

【开源】低代码 C++程序框架,Linux多线程程序

大家好&#xff0c;欢迎来到停止重构的频道。 本期介绍我们新的C低代码框架&#xff1a;Bees&#xff0c;用于编写Linux/Unix的多线程程序。 低代码框架一般是不会对C程序下手的&#xff0c;因为C程序一般是比较复杂的程序&#xff0c;光是多线程同步就够头疼的了。 但是我们…

数据库的sql语句

本篇文章主要用来收集项目开发中&#xff0c;遇到的各种sql语句的编写。 1、根据user表的role_id字段&#xff0c;查询role表。 sql语句&#xff1a;使用JOIN连接两个表 SELECT u.*,r.rolename FROM user u JOIN role r ON u.role_id r.id WHERE u.id 1; 查询结果&#xff1a…