LeetCode题练习与总结:有序链表转换二叉搜索树--109

一、题目描述

给定一个单链表的头节点  head ,其中的元素 按升序排序 ,将其转换为平衡二叉搜索树。

示例 1:

输入: head = [-10,-3,0,5,9]
输出: [0,-3,9,-10,null,5]
解释: 一个可能的答案是[0,-3,9,-10,null,5],它表示所示的高度平衡的二叉搜索树。

示例 2:

输入: head = []
输出: []

提示:

  • head 中的节点数在[0, 2 * 10^4] 范围内
  • -10^5 <= Node.val <= 10^5

二、解题思路

为了将一个升序链表转换为平衡的二叉搜索树(BST),我们可以利用链表的特性以及BST的性质。由于链表是升序的,我们可以通过快慢指针的方法找到链表的中间节点,这个中间节点就可以作为BST的根节点。然后,我们可以递归地将链表的前半部分转换为根节点的左子树,将链表的后半部分转换为根节点的右子树。

具体步骤如下:

  1. 使用快慢指针找到链表的中间节点,慢指针所在的位置即为中间位置,快指针用于确定慢指针的位置。

  2. 将慢指针指向的节点作为当前子树的根节点。

  3. 将链表从中间节点断开,分成左右两部分。

  4. 递归地将左半部分链表转换为根节点的左子树,将右半部分链表转换为根节点的右子树。

  5. 返回根节点,完成构建。

三、具体代码

class Solution {public TreeNode sortedListToBST(ListNode head) {if (head == null) {return null;}// Step 1: Find the middle of the listListNode mid = findMiddle(head);// Step 2: The middle node will be the root of the BSTTreeNode root = new TreeNode(mid.val);// Base case when there is only one element in the listif (head == mid) {return root;}// Step 3: Recursively build the left and right subtreesroot.left = sortedListToBST(head);root.right = sortedListToBST(mid.next);return root;}// Helper function to find the middle of the listprivate ListNode findMiddle(ListNode head) {ListNode prevPtr = null;ListNode slowPtr = head;ListNode fastPtr = head;// Iterate until fastPr doesn't reach the end of the listwhile (fastPtr != null && fastPtr.next != null) {prevPtr = slowPtr;slowPtr = slowPtr.next;fastPtr = fastPtr.next.next;}// If the slow pointer is not the first node, disconnect it from the listif (prevPtr != null) {prevPtr.next = null;}return slowPtr;}
}

四、时间复杂度和空间复杂度

1. 时间复杂度
  • 查找中间节点:对于长度为 n 的链表,找到中间节点需要 O(n) 时间。
  • 递归构建左右子树:由于每次递归链表长度减半,所以递归的次数为 log(n)。
  • 每次递归中,除了递归调用本身,没有其他额外的操作。

综上所述,总的时间复杂度为 O(nlog(n))。

2. 空间复杂度
  • 递归栈空间:由于构建的是平衡二叉搜索树,递归的深度为 O(log(n)),因此递归栈的空间复杂度为 O(log(n))。
  • 辅助空间:除了递归栈之外,没有使用额外的空间。

综上所述,总的空间复杂度为 O(log(n))。

五、总结知识点

1. 链表操作

  • 遍历链表:使用while循环和指针遍历链表。
  • 快慢指针技巧:用于找到链表的中间节点,快指针每次移动两步,慢指针每次移动一步。

2. 递归

  • 递归是函数自己调用自己的过程,用于解决分而治之的问题,如这里的链表转换为二叉搜索树。

3. 二叉搜索树(BST)的性质

  • BST是一种特殊的二叉树,其中每个节点的左子树只包含小于当前节点的值,右子树只包含大于当前节点的值。

4. 平衡二叉树的构建

  • 通过选择链表的中间元素作为子树的根节点,可以保证构建出的二叉搜索树是平衡的。

5. 函数定义与调用

  • sortedListToBST 是主函数,负责启动递归过程。
  • findMiddle 是辅助函数,负责找到链表的中间节点并断开链表。

6. 指针和引用

  • 在Java中,虽然没有指针的概念,但是对象引用可以类比指针,用于操作对象。

7. 链表与树的转换

  • 将一个有序链表转换为平衡二叉搜索树,涉及到数据结构之间的转换。

8. 递归的终止条件

  • 当链表为空时,递归结束,返回null

9. 节点断开

  • 在找到中间节点后,需要将中间节点的前一个节点的next引用设置为null,从而断开链表。

以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。

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

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

相关文章

Docker安装Redis的详细教程

以下是一个使用Docker安装Redis的详细教程 1. 拉取Redis镜像 运行以下命令来从Docker Hub上拉取最新的Redis镜像&#xff1a; docker pull redis:latest如果您需要特定版本的Redis&#xff0c;可以指定版本号&#xff1a; docker pull redis:6.2.72. 运行Redis容器 以下命…

JS【详解】Set 集合 (含 Set 集合和 Array 数组的区别,Set 的 API,Set 与 Array 的性能对比,Set 的应用场景)

Set 简介 ES6 新增了数据结构 Set&#xff0c;与数组类似&#xff0c;特征如下&#xff1a; 无序元素不能重复 Set 集合和 Array 数组的区别 Set 元素不能重复&#xff0c;Array 元素可以重复Set 是无序结构&#xff0c;操作很快&#xff0c;Array 是有序结构&#xff0c;操…

分享个自用的 Nginx 加强 WordPress 防护的规则

Nginx WordPress 的组合是目前非常普及的组合了&#xff0c;我们完全可以借助 Nginx 规则来加强 WordPress 的防护&#xff0c;提高 WordPress 的安全性&#xff0c;今天明月就给大家分享个自用的 Nginx 针对 WordPress 的防护规则&#xff0c;部分规则大家只需要根据自己的需要…

基于vuestic-ui实战教程 - 页面篇

1. 简介 前面介绍了基本的内容比如如何获取动态数据&#xff0c;下面就到登录进来后的页面实现了&#xff0c;相信各位读者或多或少都有 element-uijs 的实战经历&#xff0c;那么 vuestic-uits 实现的页面又该如何写呢&#xff1f;带着疑问开启今天的学习&#xff08;声明由于…

MySQL之性能剖析(一)

MySQL之架构设计与历史 转换表的引擎 1.ALTER TABLE 将表从一个引擎修改为另一个引擎最简单的办法是使用ALTER TABLE语句。下面的语句将mytable的引擎修改为InnoDB: mysql>ALTER TABLE mytable ENGINE InnoDB;上述语法可以使用任何存储引擎。但有一个问题:需要执行很长时…

Linux系统编程学习笔记

1 前言 1.1 环境 平台&#xff1a;uabntu20.04 工具&#xff1a;vim,gcc,make 1.2 GCC Linux系统下的GCC&#xff08;GNU Compiler Collection&#xff09;是GNU推出的功能强大、性能优越的多平台编译器&#xff0c;是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执…

java设计模式介绍和使用场景

设计模式是软件开发中常用的解决问题的通用方法。每种设计模式都有其特定的使用场景&#xff0c;了解这些场景可以帮助我们更好地选择合适的设计模式来解决问题。下面是一些常见的设计模式及其使用场景&#xff1a; 单例模式 (Singleton Pattern): 使用场景&#xff1a;当一个类…

BIGO前端CICD平台

本文首发于&#xff1a;https://github.com/bigo-frontend/blog/ 欢迎关注、转载。 我是谁 BIGO前端CICD平台&#xff0c;是一个服务于前端团队的全研发周期管理平台&#xff0c;已经是我们团队日常都要使用的工具了。 该平台实现了一键创建项目、发布编排、新建迭代、checkl…

uniapp 使用vuex 在app上能获取到state,小程序获取不到

1. 在根目录下新建store目录, 在store目录下创建index.js定义状态值import Vue from vue; import Vuex from Vuex; import Vuex from vuex; Vue.use(Vuex);const store new Vuex.Store({ state: { login: false, token: , avatarUrl: , userName: }, mutations: { lo…

JavaWeb Servelt原理

Servlet简介: Servlet的主要工作&#xff1a;处理客户端请求&#xff0c;生成动态响应&#xff0c;通常用于扩展基于HTTP协议的Web服务器。 Servlet技术是Java EE规范的组成部分&#xff0c;代表了服务器端的Java程序&#xff0c;主要负责处理来自客户端的Web请求&#xff0c;…

国内信创web中间件生态

国内信创web中间件生态 东方通 官网https://www.tongtech.com/pctype/25.html 宝蓝德 官网https://www.bessystem.com/product/0ad9b8c4d6af462b8d15723a5f25a87d/info?p101 金蝶天燕 官网 https://www.apusic.com/list-117.html 中创 官网http://www.inforbus.com…

数据库数据恢复—空间不足导致sqlserver数据库连接失效的数据恢复案例

数据库数据恢复环境&#xff1a; 某品牌r520服务器&#xff0c;服务器中有7块SAS硬盘&#xff0c;这7块硬盘组建了一组2盘raid1阵列和一组5盘raid5阵列&#xff0c;raid1阵列存储空间安装操作系统&#xff0c;raid5阵列存储空间存放数据。服务器上部署sql server数据库&#xf…

野外作战武器操作3D模拟实操仿真训练以便老兵能适应不同的训练需求

强国必须强军&#xff0c;我国在军事方面的投入持续加大&#xff0c;自然在军事武器培训方面不容忽视&#xff0c;在军事领域&#xff0c;3D模拟展示不仅提升了军事训练的效率&#xff0c;还为我们提供了更加直观、真实的武器体验。 首先&#xff0c;3D军事武器模拟展示能够提供…

Nacos 2.x 系列【6】持久化

文章目录 1. 前言2. Derby3. Mysql3.1 初始化脚本3.2 服务端配置3.3 验证 4. 数据源插件 1. 前言 Nacos中的用户、租户、服务配置等信息&#xff0c;需要使用关系型数据库进行存储&#xff0c;在实际开发中&#xff0c;可能还会面临各种数据库适配问题。 2. Derby Derby是Ap…

人工智能在脉搏分析中的应用

人工智能在脉搏分析中的应用正在逐步深化&#xff0c;其凭借强大的数据处理能力和模式识别技术&#xff0c;为脉搏波信号的处理和分析带来了革命性的变化。以下是人工智能在脉搏分析中的几个主要应用&#xff1a; 脉搏波信号的采集与处理&#xff1a; 脉搏波信号作为生物医学信…

【并发小知识】

计算机五大组成部分 控制器 运算器 存储器 输入设备 输出设备 计算机的核心真正干活的是CPU&#xff08;控制器运算器中央处理器&#xff09; 程序要想计算机运行&#xff0c;它的代码必须要先由硬盘读到内存&#xff0c;之后cpu取指再执行 操作系统发展史 穿孔卡片处理…

学习java第七十九天

AOP有两种实现方式&#xff1a;静态代理和动态代理。 静态代理 静态代理&#xff1a;代理类在编译阶段生成&#xff0c;在编译阶段将通知织入Java字节码中&#xff0c;也称编译时增强。AspectJ使用的是静态代理。 缺点&#xff1a;代理对象需要与目标对象实现一样的接口&#x…

Android Studio 中gradle的bin和all区别

1.在android studio中设置安装gradle时&#xff0c;真各种版本看到眼花缭乱&#xff0c;还有疑惑gradle-*.*-all.zip与gradle-*.*-bin.zip的区别是什么。下面解压如下: bin&#xff1a; all: 其实&#xff0c;用bin就可以了&#xff0c;all文件就是多了docs(文档)和src(源码)两…

选择源代码防泄漏方案需要考虑哪些因素?

选择加密软件是确保公司数据安全和保护知识产权的重要决策。 选择合适的加密软件&#xff1a;关键因素与推荐方案 一、稳定性&#xff1a;加密软件的核心 稳定性是评估加密软件的首要因素&#xff0c;它直接关系到企业数据的安全性和业务的连续性。 避免文件损坏&#xff1…

Java基础——Optional

Optional 类主要解决的问题是臭名昭著的空指针异常NPE&#xff08;NullPointerException&#xff09; 在 Java 8 之前&#xff0c;任何访问对象方法或属性的调用都可能导致 NullPointerException&#xff1a; String isocode user.getAddress().getCountry().getIsocode().to…