LeetCode题练习与总结:排序链表--148

一、题目描述

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

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

提示:

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

二、解题思路

要解决这个问题,我们可以使用归并排序,这是一种适合链表的排序算法,因为链表的元素在内存中不是连续存储的,归并排序不需要额外的存储空间,且时间复杂度为O(n log n),是一种效率较高的排序算法。

归并排序的基本思想是将链表分成两半,分别对这两半进行排序,然后将排序好的两部分合并在一起。在链表中实现这一思想相对简单,因为只需要改变节点的next指针即可完成排序。

以下是使用归并排序对链表进行排序的步骤:

  1. 找到链表的中点,可以使用快慢指针法。
  2. 将链表从中点断开,形成两个子链表。
  3. 对两个子链表分别进行递归排序。
  4. 将两个已排序的子链表合并在一起。

三、具体代码

class Solution {
    public ListNode sortList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        // Step 1. 分割链表
        ListNode slow = head, fast = head.next;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        ListNode mid = slow.next;
        slow.next = null;

        // Step 2. 递归排序
        ListNode left = sortList(head);
        ListNode right = sortList(mid);

        // Step 3. 合并链表
        return merge(left, right);
    }

    private ListNode merge(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode current = dummy;
        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                current.next = l1;
                l1 = l1.next;
            } else {
                current.next = l2;
                l2 = l2.next;
            }
            current = current.next;
        }
        if (l1 != null) {
            current.next = l1;
        } else {
            current.next = l2;
        }
        return dummy.next;
    }
}

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

1. 时间复杂度
  • 分割链表:使用快慢指针找到中点的时间复杂度是O(n),其中n是链表的长度。
  • 递归排序:将链表分割成两半,每半的长度大约是n/2,因此递归的深度是O(log n),每次递归调用需要对两个子链表进行合并,合并的时间复杂度是O(n),所以递归排序的总时间复杂度是O(n log n)。
  • 合并链表:合并两个有序链表的时间复杂度是O(n),因为每个节点最多被访问一次。
  • 综上所述,整个算法的时间复杂度是O(n log n)。
2. 空间复杂度
  • 递归栈空间:由于归并排序是递归进行的,所以需要递归栈空间。递归的最大深度是O(log n),每个递归调用需要常数空间,所以递归栈空间的总空间复杂度是O(log n)。
  • 合并链表:合并链表时,除了输入的链表节点外,只需要一个哑节点和几个指针,不需要额外的空间,因此合并链表的空间复杂度是O(1)。
  • 综上所述,整个算法的空间复杂度是O(log n),主要取决于递归栈的空间消耗。

综合以上分析,归并排序链表的算法时间复杂度是O(n log n),空间复杂度是O(log n)。

五、总结知识点

1. 链表的基本操作:

  • 节点构成:链表由节点组成,每个节点包含数据和指向下一个节点的引用。
  • 创建与遍历:链表的创建通过连接节点实现,遍历则是通过依次访问节点的引用。
  • 分割与合并:链表的分割通过调整节点的引用实现,合并则是将两个链表的节点按特定顺序连接。

2. 递归:

  • 函数自调用:递归允许函数调用自身,用于解决可以分解为更小相似问题的大问题。
  • 分治策略:在归并排序中,递归用于将链表分成更小的部分,分别排序后再合并。

3. 快慢指针:

  • 中点查找:快慢指针技术用于找到链表的中点,快指针每次移动两步,慢指针移动一步。
  • 链表分割:当快指针到达链表末尾时,慢指针所指即为链表的中点,从而实现链表的分割。

4. 归并排序:

  • 分治算法:归并排序是一种分治算法,将数据分为两半,分别排序后再合并。
  • 时间复杂度:归并排序的时间复杂度为O(n log n),适用于链表排序。

5. 合并有序链表:

  • 比较与连接:合并两个有序链表时,比较节点值,将较小的节点连接到结果链表中。
  • 链表拼接:当一个链表为空时,将另一个链表的剩余部分接到结果链表的末尾。

6. 哑节点:

  • 辅助节点:哑节点作为辅助节点,用于简化链表操作的边界条件处理。
  • 处理头节点:在合并链表时,使用哑节点作为结果链表的起始节点,避免处理头节点的特殊情况。

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTTP与HTTPS的主要区别

HTTP&#xff08;超文本传输协议&#xff09;与HTTPS&#xff08;超文本传输安全协议&#xff09;的主要区别在于安全性、数据传输方式、默认使用的端口以及对网站的影响。 一、安全性&#xff1a; HTTP是一种无加密的协议&#xff0c;数据在传输过程中以明文形式发送&#x…

2024年APMCM亚太杯中文赛A题——飞行器外形的优化问题

飞行器外形的优化问题 解题思路问题一第一问结果第一问代码 完整答案 本篇文章为大家分享2024年APMCM亚太杯中文赛A题——飞行器外形的优化问题的解题思路以及第一问的完整求解代码与结果&#xff0c;四问的完整解答请看文章最后&#xff01; 解题思路 飞行器是在大气层内或大…

粤港澳大湾区人工智能资本对接会”成功举办!

为促进惠州仲恺高新区人工智能产业的发展&#xff0c;推动惠深两地产业资源深度协同与合作&#xff0c;也为吸引更多的优质项目与投融资机构为惠州仲恺高新区产业发展注入动力&#xff0c;加速深圳人工智能相关产业资源落地仲恺。2024年06月26日&#xff0c;由仲恺高新区科技创…

C#用反射机制调用dll文件的字段、属性和方法

1、创建dll文件 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace CLStudent {public class Student{//字段public string Name "Tom";//属性public double ChineseScore { get; s…

【Python系列】数字的bool值

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

1990-2021年297个地级市RD内部经费支出数据

地级市内部经费支出数据为研究者提供了了解地方政府在科研活动上的投入情况的重要视角。以下是对297个地级市R&D内部经费支出数据的介绍&#xff1a; 数据简介 定义&#xff1a;地级市内部经费支出是指地级市政府在一定时期内用于科研活动的经费支出。用途&#xff1a;这…

前端面试题(CSS篇三)

一、简单介绍使用图片 base64 编码的优点和缺点。 base64是一种图片处理格式&#xff0c;通过特定的算法将图片编码为一长串字符串&#xff0c;在页面显示的时候&#xff0c;可以使用该字符串来代替图片的url属性。 使用base64的优点: 减少一个图片的http请求 使用base64的缺点…

微信⼩程序的电影推荐系统-计算机毕业设计源码76756

摘 要 随着互联网的普及和移动互联网的发展&#xff0c;人们对于获取信息的便捷性和高效性要求越来越高。电影作为一种受众广泛喜爱的娱乐方式&#xff0c;电影推荐系统的出现为用户提供了更加个性化和精准的电影推荐服务。微信小程序作为一种轻量级应用形式&#xff0c;在用户…

Spring Boot Vue 毕设系统讲解1

项目结构 包说明 db&#xff1a;文件夹是存放数据脚本文件的 annotation&#xff1a; 系统自定义注解 config&#xff1a;系统定义的配置类 controller&#xff1a; 系统接口控制器类 dao&#xff1a; 系统dao类编写数据库查询方法和数据库交互 entity&#xff1a;数据库…

【python基础】—如何理解安装程序时要配置Widows和DOS操作系统中的path环境变量?

文章目录 前言一、环境变量是什么&#xff1f;二、为什么需要设置环境变量&#xff1f;三、配置anaconda的环境变量 前言 在安装一些程序的时候&#xff0c; 我们总是需要将安装路径配置到正在使用电脑的环境变量里。为什么要进行这一步呢&#xff1f;本文主要解释Widows和DOS…

c++ word转换为pdf

在windows系统下&#xff0c;使用QAxObject效果是最好的 转60多兆的文件速度还是可以的&#xff0c;不建议使用多线程&#xff0c;因为多线程会多次调用转换函数&#xff0c;导致程序一直运行&#xff0c;只有全部转换完成后&#xff0c;程序才能继续向下运行&#xff0c;但是c…

Cesium 二三维热力图

Cesium 二三维热力图 原理&#xff1a;主要依靠heatmap.js包来实现 效果图&#xff1a;

Java面试八股之MYISAM和INNODB有哪些不同

MYISAM和INNODB有哪些不同 MyISAM和InnoDB是MySQL数据库中两种不同的存储引擎&#xff0c;它们在设计哲学、功能特性和性能表现上存在显著差异。以下是一些关键的不同点&#xff1a; 事务支持&#xff1a; MyISAM 不支持事务&#xff0c;没有回滚或崩溃恢复的能力。 InnoDB…

关于在自行封装的组件库中(使用vue-class-component)使用Vue-i18n无法正常翻译的解决办法

文章目录 介绍背景现象1解决办法 现象2原因分析解决办法 最终方案 介绍 大家或多或少都用过别人封装的组件库&#xff0c;甚至有人或者公司内有自行封装的一些公用组件库&#xff0c;而国际化翻译现在已经是各大项目中必不可少的一个插件了&#xff0c;但组件库中使用 i18n 进…

文章解读与仿真程序复现思路——太阳能学报EI\CSCD\北大核心《绿电交易场景下计及温控负荷的高铁站两阶段调度策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

成人高考专升本专业有哪些?深职训学校帮您圆梦

成人高考专升本专业选择多样化 成人高考专升本考试是成人高考的一种考试形式&#xff0c;主要面向已经参加工作的人员&#xff0c;旨在选拔具有高等教育需求的成人考生&#xff0c;录取到高等学校继续深造。成人高考专升本考试的专业选择非常多样化&#xff0c;涵盖了人文社科…

Python酷库之旅-第三方库Pandas(006)

目录 一、用法精讲 10、pandas.DataFrame.to_excel函数 10-1、语法 10-2、参数 10-3、功能 10-4、返回值 10-5、说明 10-6、用法 10-6-1、数据准备 10-6-2、代码示例 10-6-3、结果输出 11、pandas.ExcelFile类 11-1、语法 11-2、参数 11-3、功能 11-4、返回值 …

RNN文献综述

循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种专门用于处理序列数据的神经网络模型。它在自然语言处理、语音识别、时间序列预测等领域有着广泛的应用。本文将从RNN的历史发展、基本原理、应用场景以及最新研究进展等方面进行综述。 历…

大数据平台之数据同步

数据同步也成为CDC (Chanage Data Capture) 。Change Data Capture (CDC) 是一种用于跟踪和捕获数据库中数据变更的技术&#xff0c;它可以在数据发生变化时实时地将这些变更捕获并传递到下游系统。以下是一些常用的开源 CDC 方案&#xff1a; 1. Flink CDC Flink CDC 是基于 …

Linux——目录结构

基本介绍 Linux的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录"/"&#xff0c;然后在根目录下再创建其他的目录 在Linux中&#xff0c;有一句经典的话&#xff1a;在Linux世界里&#xff0c;一切皆文件 Linux中根目录下的目录 具体的…