Files
LeetCode/链表/12. 排序链表.md
T
2025-10-04 12:43:05 +08:00

2.3 KiB
Raw Blame History

排序链表

题目

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

示例 1:

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

输入:head = [-1,5,3,4,0] 输出:[-1,0,3,4,5] 示例 3:

输入:head = [] 输出:[]

提示:

链表中节点的数目在范围 [0, 5 * 104] 内 -105 <= Node.val <= 105

进阶:你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

思路

  • 归并排序
    • 拆分
      • 快慢指针
    • 合并

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode sortList(ListNode head) {
        // -- Divide -> Sort -> Merge --
        // Special
        if (head == null || head.next == null) {
            return head;
        }

        // Init: slow, fast, dummyHead
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode slow = dummyHead;
        ListNode fast = dummyHead;
        while (fast.next != null && fast.next.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        // Divide: [headA .... tailA(slow)] [headB(slow.next) ... tailB]
        ListNode headA = head;
        ListNode headB = slow.next;
        slow.next = null;
        // Sort
        headA = sortList(headA);
        headB = sortList(headB);
        // Merge
        return mergeList(headA, headB);
    }

    public ListNode mergeList(ListNode headA, ListNode headB) {
        // Init: dummyHead, tail
        ListNode dummyHead = new ListNode(-1);
        ListNode tail = dummyHead;
        // Traverse: Merge
        while (headA != null && headB != null) {
            int valA = headA.val;
            int valB = headB.val;
            if (valA < valB) {
                tail.next = headA;
                headA = headA.next;
            } else {
                tail.next = headB;
                headB = headB.next;
            }
            tail = tail.next;
        }
        // Operation: After
        tail.next = headA == null ? headB : headA;
        return dummyHead.next;
    }
}