返回

LeetCode刷题记录-剑指 Offer II 029. 排序的循环链表

前端

前言

数据结构与算法在计算机科学中占据着举足轻重的作用,而链表作为一种常见的数据结构,在实际应用中有着广泛的场景。在LeetCode中,链表相关题目也占据了相当大的比重。本文将带领大家深入分析剑指 Offer II 029. 排序的循环链表这道题目,旨在帮助读者掌握解决这类循环链表排序问题的技巧,提升数据结构与算法的实战能力。

题目要求

给定一个循环链表,其节点包含一个整型值。将这个循环链表按非递减顺序排序,返回排序后的循环链表的头节点。

示例:

输入:head = [3,2,1]
输出:[1,2,3]

思路分析

要对循环链表进行排序,我们首先需要将循环链表转换成一个普通链表,然后再使用排序算法对普通链表进行排序。最后,再将排序后的普通链表转换成循环链表即可。

代码实现

def sortList(head):
    # 将循环链表转换成普通链表
    if not head or not head.next:
        return head

    # 找到循环链表的入口结点
    slow = head
    fast = head.next
    while fast != slow:
        slow = slow.next
        fast = fast.next.next

    # 断开循环链表,得到普通链表的头结点
    entry = slow
    while slow.next != entry:
        slow = slow.next
    slow.next = None

    # 对普通链表进行排序
    dummy = ListNode(0)
    dummy.next = head
    insertion_sort(dummy)

    # 将排序后的普通链表转换成循环链表
    new_head = dummy.next
    while new_head.next:
        new_head = new_head.next
    new_head.next = entry

    return entry

def insertion_sort(head):
    cur = head.next
    while cur:
        pre = head
        while pre.next != cur and pre.next.val < cur.val:
            pre = pre.next
        if pre.next == cur:
            cur = cur.next
            continue
        next = cur.next
        cur.next = pre.next
        pre.next = cur
        cur = next

时间复杂度分析

将循环链表转换成普通链表的时间复杂度为O(n),其中n为链表的长度。使用插入排序对普通链表进行排序的时间复杂度为O(n^2)。将排序后的普通链表转换成循环链表的时间复杂度为O(n)。因此,总的时间复杂度为O(n^2)。

空间复杂度分析

该算法使用了一个额外的dummy结点和一个变量pre,因此空间复杂度为O(1)。

总结

剑指 Offer II 029. 排序的循环链表这道题目考察了对循环链表的理解和排序算法的掌握程度。通过将循环链表转换成普通链表,使用插入排序对普通链表进行排序,再将排序后的普通链表转换成循环链表,可以有效地解决该问题。掌握此类题目的解题思路,对于提升对链表数据结构和排序算法的理解大有裨益。