力扣148.排序链表

一、递归

思路:

利用之前做过的题目,获取链表中点(876题),将链表分为两段,参考合并有序链表(21题),将前半段和后半段进行排序后合并,但与之前不同的是,这里并不一定是有序的,就通过递归方式来处理,最后向上返回的一定是两个有序链表之间的合并。

注意:

获取链表中点相比于原题增加了个pre,pre 的作用是记录 slow 指针的前一个节点。当循环结束时,slow 指针指向链表的中间节点,而 pre 指针指向中间节点的前一个节点。

通过设置 pre.next = None,可以将链表从中间节点处分割成两个独立的链表。如果不使用 pre,就无法直接操作中间节点的前一个节点,也就无法完成链表的分割,只能返回中间节点是什么,而无法对前半段链表和后半段链表分开处理

代码:

python 复制代码
class Solution:
    # 876. 链表的中间结点
    def midNode(self, head):
        slow = fast = head
        while fast and fast.next:
            pre = slow
            slow = slow.next
            fast = fast.next.next
        pre.next = None
        return slow

    # 21. 合并两个有序链表
    def merge(self, list1, list2):
        cur = dum = ListNode()
        while list1 and list2:
            if list1.val < list2.val:
                cur.next = list1
                list1 = list1.next
            else:
                cur.next = list2
                list2 = list2.next
            cur = cur.next
        cur.next = list1 if list1 else list2
        return dum.next

    def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        # 如果链表为空或者只有一个节点,无需排序
        if head is None or head.next is None:
            return head

        # 找到中间节点 head2,并断开 head2 与其前一个节点的连接
        # 比如 head=[4,2,1,3],那么 midNode 调用结束后 head=[4,2] head2=[1,3]
        head2 = self.midNode(head)

        head = self.sortList(head)
        head2 = self.sortList(head2)

        return self.merge(head, head2)

复杂度分析:

  • 时间复杂度:O(nlogn),其中 n 是链表长度。递归式 T(n)=2T(n/2)+O(n),由主定理可得时间复杂度为 O(nlogn)。从图形上理解,递归深度是 O(logn),每一层的链表长度之和是 O(n)。计算高为 O(logn),底边长为 O(n) 的矩形面积,得到 O(nlogn)。
  • 空间复杂度:O(logn)。递归需要 O(logn) 的栈开销。

参考:

https://leetcode.cn/problems/sort-list/solutions/2993518/liang-chong-fang-fa-fen-zhi-die-dai-mo-k-caei

二、归并排序

思路:

暂时看不懂。。后面再来填坑吧我累了...

相关推荐
水蓝烟雨2 小时前
1931. 用三种不同颜色为网格涂色
算法·leetcode
leoufung4 小时前
LeetCode 76:Minimum Window Substring 题解与滑动窗口思维详解
算法·leetcode·职场和发展
风筝在晴天搁浅5 小时前
LeetCode 92.反转链表Ⅱ
算法·leetcode·链表
普贤莲花9 小时前
【2026年第18周---写于20260501】---舍得
程序人生·算法·leetcode
m0_629494739 小时前
LeetCode 热题 100-----16.除了自身以外数组的乘积
数据结构·算法·leetcode
We་ct10 小时前
LeetCode 97. 交错字符串:动态规划详解
前端·算法·leetcode·typescript·动态规划
无敌昊哥战神10 小时前
【LeetCode 37】解数独 (Sudoku Solver) —— 回溯法详解 (Python/C/C++)
c语言·c++·python·算法·leetcode
风筝在晴天搁浅10 小时前
LeetCode 162.寻找峰值
算法·leetcode
罗超驿11 小时前
双指针算法经典案例:LeetCode 283. 移动零(Java详解)
java·算法·leetcode
人道领域11 小时前
【数据结构与算法分析】二叉树面试通关手册:遍历图解 · 分类对比 · 代码模板
数据结构·算法·leetcode·深度优先