From e75195df41613616ed08e6cd8c4c4d71c906948a Mon Sep 17 00:00:00 2001 From: Wonder Date: Sat, 4 Oct 2025 12:43:05 +0800 Subject: [PATCH] =?UTF-8?q?=20=F0=9F=94=84Update:=20=E6=8E=92=E5=BA=8F?= =?UTF-8?q?=E9=93=BE=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 链表/12. 排序链表.md | 104 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 链表/12. 排序链表.md diff --git a/链表/12. 排序链表.md b/链表/12. 排序链表.md new file mode 100644 index 0000000..6d4e10c --- /dev/null +++ b/链表/12. 排序链表.md @@ -0,0 +1,104 @@ +# 排序链表 + +## 题目 + +给你链表的头结点 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) 时间复杂度和常数级空间复杂度下,对链表进行排序吗? + +## 思路 + +- 归并排序 + - 拆分 + - 快慢指针 + - 合并 + + +## 代码 + +```java +/** + * 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; + } +} +``` \ No newline at end of file