leetcode:114. 二叉树展开为链表

embedded/2024/11/22 5:38:14/

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

  • 展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
  • 展开后的单链表应该与二叉树 先序遍历 顺序相同。

示例 1:

输入:root = [1,2,5,3,4,null,6]
输出:[1,null,2,null,3,null,4,null,5,null,6]

示例 2:

输入:root = []
输出:[]

示例 3:

输入:root = [0]
输出:[0]

提示:

  • 树中结点数在范围 [0, 2000] 内
  • -100 <= Node.val <= 100

进阶:你可以使用原地算法O(1) 额外空间)展开这棵树吗?

步骤1:问题定义与分析

问题性质
给定一个二叉树的根节点 root,需要将二叉树“展开”为一个单链表,要求:

  • 展开的单链表与二叉树的 先序遍历顺序 相同。
  • 链表right 指针指向下一个节点,left 指针始终为 null

输入条件

  1. 二叉树节点个数 n 的范围是 [0, 2000]
  2. 树节点值的范围是 [-100, 100]

输出条件: 返回一个以二叉树先序遍历顺序展开的链表

限制与边界条件

  1. 空树:root = [] 应返回 []
  2. 单节点树:root = [0] 应直接返回 [0]
  3. 完全二叉树或非完全二叉树,均需考虑遍历顺序正确性。
  4. 要求实现原地算法O(1) 空间复杂度)。

步骤2:算法设计

目标算法思路: 将树“原地”转换为单链表,需要:

  1. 遍历树的所有节点,按照先序遍历(根 -> 左 -> 右)顺序重新连接 right 指针。
  2. 在不使用额外数据结构(如栈)的情况下,原地展开,保持 O(1) 空间复杂度。

算法步骤

  1. 使用递归法(基础版本)

    • 通过递归实现先序遍历,并将节点按顺序重新连接。
    • 时间复杂度:O(n),每个节点访问一次。
    • 空间复杂度:O(h)h 为树的高度(递归栈消耗),最差为 O(n)
  2. 优化为 Morris 遍历法(原地实现)

    • 利用 Morris 遍历的思想,避免使用额外空间。
    • 每次找到当前节点左子树的最右节点,将其 right 指针指向当前节点的右子树,然后移动到下一个节点。
    • 时间复杂度:O(n)
    • 空间复杂度:O(1)

步骤3:代码实现

以下是基于 Morris 遍历 的 C++ 实现

步骤4:优化与启发

  1. 算法优化的思考

    • Morris 遍历充分利用了树的空闲指针,不依赖额外栈空间,将空间复杂度降到 O(1)
    • 时间复杂度保持为 O(n),对每个节点的访问次数为常数级。
  2. 启发

    • 在解决树的问题时,可以通过改变节点连接关系而减少空间消耗。
    • Morris 遍历的思想广泛适用于中序、前序遍历的优化。
  3. 处理大规模数据

    • 由于时间复杂度为线性,且空间复杂度为常数,该算法能够高效处理节点数达 2000 的二叉树。
    • 对于深度极大的树(如链式树结构),递归法可能引发栈溢出,而 Morris 遍历能够规避这一问题。

步骤5:实际应用场景

应用场景: 该算法的思想可以应用于以下场景:

  1. 数据结构转换
    • 在嵌入式系统或资源受限的场景下,原地对数据结构进行转换(如二叉树展开为链表)。
  2. 内存优化
    • 例如在数据库索引中,通过类似方法将 B+ 树的结构转换为顺序链表,从而提高访问效率。

具体实例: 在文件系统中,将目录结构表示为二叉树。为了遍历所有文件(先序顺序),可以利用此算法原地将目录树展开为链表,并顺序访问所有文件路径,无需占用额外的栈或队列。

实现方法

  • 文件树的节点存储文件夹路径。
  • 调用 flatten 方法后,生成的链表通过 right 指针依次链接所有文件夹路径。
  • 遍历链表即可访问每个文件夹,简化操作流程并节省内存。

以上解决方案既考虑了算法设计的高效性,也注重实际应用的可行性和通用性。


http://www.ppmy.cn/embedded/139536.html

相关文章

如何在 Ubuntu 上设置 SSH X11 转发并访问远程图形界面

1. 前言 当我们在远程服务器上运行需要图形界面的程序时&#xff0c;通常需要使用 SSH 来连接服务器并通过 X11 转发将远程的图形界面显示到本地机器。本文将详细介绍如何使用 SSH 命令和相关的配置&#xff0c;来通过 X11 转发在 Ubuntu 上远程访问服务器的图形界面。 2. SS…

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域&#xff0c;数据可视化是一个至关重要的环节。通过可视化&#xff0c;我们可以直观地理解数据的特征和趋…

springboot中设计基于Redisson的分布式锁注解

如何使用AOP设计一个分布式锁注解&#xff1f; 1、在pom.xml中配置依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.26</version></dependency><dependenc…

什么是Git,有什么特点

版本控制工具Git简介 一、Git的由来 Git 是一种分布式版本控制系统&#xff0c;由 Linux 之父 Linus Torvalds 于 2005 年创建。当时&#xff0c;Linux 内核开发团队需要一个高效的版本控制系统来管理庞大的代码库。在此之前&#xff0c;他们使用的是 BitKeeper&#xff0c;这…

【第二十一周】网络爬虫实践

目录 摘要Abstract案例&#xff1a;使用 Python 抓取微博评论数据一、数据来源分析1.明确需求2.抓包分析 二、代码实现步骤1.发送请求2.获取数据3.解析数据4.保存数据5.批量采集数据6.封装函数 总结 摘要 本周主要完成了陶博的大语言课程中布置的一个爬虫实践任务&#xff0c;…

Java算法OJ(7)随机快速排序

目录 1.前言 2.正文 1. 快速排序的基本原理 2. 随机快速排序的改进 3. 随机快速排序的步骤 3.小结 1.前言 哈喽大家好吖&#xff0c;今儿给大家带来算法—随机快速排序相关知识点&#xff0c;废话不多说让我们开始。 2.正文 在了解随机快排之前&#xff0c;先了解一下…

跨平台WPF框架Avalonia教程 八

构建跨平台应用程序 本指南介绍了Avalonia&#xff0c;并概述了如何构建跨平台应用程序&#xff0c;以最大程度地重用代码&#xff0c;并在所有主要平台&#xff08;Windows、Linux、macOS、iOS、Android和WebAssembly&#xff09;上提供高质量的用户界面体验。 与Xamarin.Fo…

【贪心算法】贪心算法四

贪心算法四 1.最长回文串2.增减字符串匹配3.分发饼干4.最优除法 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603; 1.最长回文串 题目链接&…