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

二、归并排序

思路:

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

相关推荐
土司大王7 小时前
LeetCode hot100 回溯专题总结:Java 通用模板、决策树模型
java·算法·leetcode·决策树
a187927218319 小时前
【算法】链表(二):链表上的双指针——变速、异链与定距,和一份路程账本
数据结构·算法·leetcode·链表·go·指针·环形链表
hanlin0313 小时前
刷题笔记:力扣第287题-寻找重复数
笔记·算法·leetcode
橘子汽水16814 小时前
Leetcode 322 279 零钱兑换,完全平方数
算法·leetcode
土司大王15 小时前
LeetCode hot100——51.N 皇后:Java 回溯模板、列与对角线剪枝、O(n!) 复杂度分析
java·leetcode·剪枝
木井巳16 小时前
【记忆化搜索】斐波那契数
java·算法·leetcode·深度优先·剪枝·推荐算法
Navigator_Z1 天前
LeetCode //C - 1240. Tiling a Rectangle with the Fewest Squares
c语言·算法·leetcode
稻米哟1 天前
力扣100——双指针
算法·leetcode
橘子汽水1681 天前
Leetcode 198,118打家劫舍,杨辉三角
算法·leetcode