力扣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

二、归并排序

思路:

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

相关推荐
Q741_147几秒前
每日一题 3740. 三个相等元素之间的最小距离 I 3741. 三个相等元素之间的最小距离 II 模拟 哈希表 C++ 题解
c++·算法·leetcode·模拟·数组·哈希表
alphaTao10 分钟前
LeetCode 每日一题 2026/4/6-2026/4/12
python·算法·leetcode
独孤--蝴蝶13 分钟前
leetcode-动态规划三种问题的异同点
算法·leetcode·动态规划
人道领域1 小时前
【LeetCode刷题日记】:从 LeetCode 经典题看哈希表的场景化应用---数组、HashSet、HashMap 选型与算法实战
算法·leetcode·面试
承渊政道1 小时前
【优选算法】(实战攻坚BFS之FloodFill、最短路径问题、多源BFS以及解决拓扑排序)
数据结构·c++·笔记·学习·算法·leetcode·宽度优先
skywalker_1110 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia10 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
wfbcg11 小时前
每日算法练习:LeetCode 209. 长度最小的子数组 ✅
算法·leetcode·职场和发展
_日拱一卒11 小时前
LeetCode:除了自身以外数组的乘积
数据结构·算法·leetcode
wsoz12 小时前
Leetcode普通数组-day5、6
c++·算法·leetcode·数组