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

二、归并排序

思路:

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

相关推荐
iAkuya2 小时前
(leetcode)力扣100 46二叉树展开为链表(递归||迭代||右子树的前置节点)
windows·leetcode·链表
程序员-King.3 小时前
day151—双端队列—找树左下角的值(LeetCode-513)
算法·leetcode·二叉树·双端队列·队列
苦藤新鸡3 小时前
15 .数组右移动k个单位
算法·leetcode·动态规划·力扣
氷泠4 小时前
路径总和系列(LeetCode 112 & 113 & 437 & 666)
leetcode·前缀和·深度优先·路径总和
橘颂TA4 小时前
【剑斩OFFER】算法的暴力美学——力扣 130 题:被围绕的区域
算法·leetcode·职场和发展·结构与算法
一分之二~4 小时前
回溯算法--解数独
开发语言·数据结构·c++·算法·leetcode
程序员-King.5 小时前
day154—回溯—分割回文串(LeetCode-131)
算法·leetcode·深度优先·回溯
程序员-King.5 小时前
day155—回溯—组合(LeetCode-77)
算法·leetcode·回溯
程序员-King.5 小时前
day152—回溯—电话号码的字母组合(LeetCode-17)
算法·leetcode·深度优先·递归