Medium | LeetCode 148. 排序連結串列 | 歸併排序(遞迴)
阿新 • • 發佈:2021-06-20
148. 排序連結串列
難度中等1181
給你連結串列的頭結點 head
,請將其按 升序 排列並返回 排序後的連結串列 。
進階:
- 你可以在
O(n log n)
時間複雜度和常數級空間複雜度下,對連結串列進行排序嗎?
示例 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
解題思路
方法一: 歸併排序(遞迴)
public ListNode sortList(ListNode head) { return sortList(head, null); } /** * 排序[head, tail)這部分的連結串列, 這是一個左閉右開的連結串列 * @param head 連結串列頭部 * @param tail 連結串列尾部 * @return 排序後的連結串列 */ public ListNode sortList(ListNode head, ListNode tail) { // 空連結串列直接返回 if (head == null) { return head; } // 只有一個節點 if (head.next == tail) { // 將next指標置位空 head.next = null; return head; } // 快慢指標法找到連結串列的中間節點 ListNode slow = head, fast = head; while (fast != tail) { // 慢指標每次走一步 slow = slow.next; // 快指標每次走兩步 fast = fast.next; if (fast != tail) { fast = fast.next; } } // 將連結串列切成兩塊分別遞迴進行歸併排序 ListNode mid = slow; ListNode list1 = sortList(head, mid); ListNode list2 = sortList(mid, tail); return merge(list1, list2); } public ListNode merge(ListNode la, ListNode lb) { ListNode dumpHead = new ListNode(); ListNode pre = dumpHead; ListNode pa = la, pb = lb; while (pa != null && pb != null) { if (pa.val <= pb.val) { pre.next = pa; pa = pa.next; } else { pre.next = pb; pb = pb.next; } pre = pre.next; } pre.next = (pa == null) ? pb : pa; return dumpHead.next; }