【LeetCode】148. 排序链表

news/2025/4/2 22:50:56/文章来源:https://www.cnblogs.com/yunxizhijian/p/18804326

leetcode

 

解题思路

对链表进行升序排序的最佳方法是 ​归并排序(Merge Sort)​,其时间复杂度为 O(n log n),空间复杂度为 O(log n)(递归调用栈深度)。核心步骤如下:

  1. 分割链表:使用快慢指针找到链表中点,将链表分为左右两部分。
  2. 递归排序:对左右子链表分别递归排序。
  3. 合并有序链表:合并两个已排序的链表,生成最终有序链表。

代码实现

// 定义链表节点结构体
type ListNode struct {Val  intNext *ListNode
}// 主函数:归并排序入口
func sortList(head *ListNode) *ListNode {// 递归终止条件:空链表或单节点if head == nil || head.Next == nil {return head}// Step 1: 找到链表中点并分割mid := getMid(head)left := headright := mid.Nextmid.Next = nil // 断开左右链表// Step 2: 递归排序左右子链表left = sortList(left)right = sortList(right)// Step 3: 合并有序链表return merge(left, right)
}// 快慢指针找中点(慢指针停在中间左侧)
func getMid(head *ListNode) *ListNode {slow, fast := head, head.Nextfor fast != nil && fast.Next != nil {slow = slow.Nextfast = fast.Next.Next}return slow
}// 合并两个有序链表
func merge(l1, l2 *ListNode) *ListNode {dummy := &ListNode{} // 虚拟头节点简化操作tail := dummy// 比较节点值,按升序连接for l1 != nil && l2 != nil {if l1.Val < l2.Val {tail.Next = l1l1 = l1.Next} else {tail.Next = l2l2 = l2.Next}tail = tail.Next}// 处理剩余节点if l1 != nil {tail.Next = l1} else {tail.Next = l2}return dummy.Next
}

代码解析

  1. 结构体定义
    ListNode 结构体包含 Val(节点值)和 Next(指向下一节点的指针),是链表的标准表示。

  2. 快慢指针分割链表

    • 快指针 fast 每次移动两步,慢指针 slow 每次移动一步。当 fast 到达链表末尾时,slow 位于中间节点的左侧(偶数长度链表)或正中间(奇数长度链表)。
    • 通过 mid.Next = nil 断开链表,确保左右子链表独立排序。
  3. 递归排序与合并

    • 递归终止条件处理空链表和单节点情况,直接返回无需操作。
    • merge 函数利用虚拟头节点 dummy 简化合并逻辑,逐个比较节点值并按升序连接。

复杂度分析

指标说明
时间复杂度 O(n log n) 分治策略,每层递归处理 n 个节点
空间复杂度 O(log n) 递归调用栈深度(平衡树高度)

示例验证

func main() {// 示例1:输入 [4,2,1,3] → 输出 [1,2,3,4]head1 := &ListNode{4, &ListNode{2, &ListNode{1, &ListNode{3, nil}}}}sorted1 := sortList(head1)printList(sorted1) // 输出:1 → 2 → 3 → 4// 示例2:输入 [-1,5,3,4,0] → 输出 [-1,0,3,4,5]head2 := &ListNode{-1, &ListNode{5, &ListNode{3, &ListNode{4, &ListNode{0, nil}}}}}sorted2 := sortList(head2)printList(sorted2) // 输出:-1 → 0 → 3 → 4 → 5// 示例3:输入 [] → 输出 []var head3 *ListNodesorted3 := sortList(head3)printList(sorted3) // 输出:空
}// 辅助函数:打印链表
func printList(head *ListNode) {for head != nil {fmt.Printf("%d → ", head.Val)head = head.Next}fmt.Println("nil")
}

关键点与边界处理

  1. 快慢指针初始值
    fast 初始化为 head.Next,确保偶数长度链表分割时 slow 停在左半部分末尾(如示例1的分割点为节点2)。

  2. 合并剩余节点
    merge 函数末尾直接链接剩余链表,避免遗漏未处理节点。

  3. 空链表处理
    主函数优先判断 head == nil,直接返回空链表。


与其他方法对比

方法优点缺点适用场景
归并排序 时间/空间最优,稳定性高 递归可能栈溢出 大规模链表排序
插入排序 代码简单,无需额外空间 时间复杂度 O(n²) 小规模或基本有序链表
快速排序 平均时间 O(n log n) 最坏情况 O(n²) 内存敏感场景

总结

通过归并排序的分治策略,该实现高效解决了链表排序问题。

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

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

相关文章

算法备案没产品可以申请吗?

算法备案复审阶段涉及产品信息填报,所以一度让一些开发者有这样的错误认知:只有等产品要上线了,才能火急火燎地去申请算法备案。但这个观点其实是错误的,其实开发者也可以在没有具体产品的情况下发起算法备案申请。只要材料合法合规,也能取得备案号。下面是一些具体信息介…

工业通信协议“牵手密码”,Ethernet IP转Profinet网关的桥梁魔法

在当前工业自动化领域,实时以太网技术已经成为至关重要的通信标准之一。Profinet和EtherNetIP作为两种广泛采用的实时以太网协议,各自拥有其独特的性能优势和适用场景。本文旨在探讨稳联技术Profinet转EtherNetIP网关WL-PN-EIPM的功能,并评估其在节能实施与监测方面的应用价…

LeetCode刷题-动态规划-爬楼梯

LeetCode刷题-动态规划-爬楼梯 题目: 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 示例 1: 输入:n = 2 输出:2 解释:有两种方法可以爬到楼顶。1 阶 + 1 阶 2 阶 示例 2:输入:n = 3 输出:3 解释:有…

【攻防世界】Hidden-Message

⭕、知识点 流量分析/端口号隐写/tshark/json文件处理 一、题目二、解法 1、端口号个位呈现有规律的01交替,可能隐藏信息。 2、为便于提取信息,使用kali的tshark对其进行转存 tshark -r input.pcap -T json > output.txt注意在使用tshark时应避免使用root账户 否则会出现如…

022 props组件交互

.vue 的文件,就是一个组件,每个.vue 文件就是每个页面html 的时候,每个页面都是一个 htmlvue2 和 vue3 的生命周期钩子是不同的components:常用的组件,公共的组件views:用来存放页面的新建项目,删除HelloWorld.vue components也删除views删除 这个index.js删除 这两页面…

客户端打开BI报表提示 Your current browser is not supported”

win7的打开会报这个问题, win11可以正常打开, 应该是环境差异导致。

Linux-常用命令(3)

Linux-常用命令(3)Linux常用命令 查看文件 cat命令 cat命令可以创建一个或者多个文件、查看文件内容、连接文件,常用于查看文件内容 cat 文件名 //显示文件内容 cat -n 文件名 //显示文件内容,并显示行号 cat - 文件名 //显示文件内容(包括不可见字符)系统时间 date命令…

【EI】机器人与传感器网络国际会议(RoSeN 2025)

第一届机器人与传感器网络国际会议(RoSeN 2025)将于2025年5月16-18日在贵阳举行,会议将围绕机器人展开的在机器人、人机交互、传感、智能控制等相关研究领域,邀请国内外数位在此领域学术卓越的学者专家做相关致辞与报告,共同探讨机器人发展最新发展方向及行业前沿动态。会…

[转]玩客云刷armbian后根目录扩展

地址:玩客云刷armbian后根目录扩展_IT码迹最近拼夕夕搞了个玩客云,自己懒得刷机(太麻烦,还要绝育什么的)所以直接买的刷好的,商家送了个U盘32G已经做好了镜像。 商家镜像刷了不少东西除了openwrt,其他几个docker镜像都是armbian比较好用的。不过在我要安装其他插件的时候发…

生成未来:解码智能技术驱动的产业革命

在人工智能浪潮的推动下,AI生图与视频技术正以惊人的速度重塑人类的生产方式。从一张图片的生成到一段视频的秒级渲染,技术的突破不仅解放了生产力,更催生了全新的商业生态。这场变革的核心,在于用算法替代重复劳动,以智能激发无限创意,而这一切仅仅是开端。 一、技术突破…

云终端远程自动调用开关机功能

云桌面项目由于缺少一键关机和开机功能,通过Linux实现自动化调用开机和关机 1、收集所有终端信息的MAC地址收集方式可以采用ipscan25.exe也可以通过cmd下arp -a方式收集MAC地址,同时记录MAC可以IP地址的对应关系。2、所有终端安装openssh使用系统自带或者下载OpenSSH-Win64-v…