1. 程式人生 > 其它 >排序連結串列(歸併排序,迭代)

排序連結串列(歸併排序,迭代)

目錄

1 題目描述

給你連結串列的頭結點 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 * 10 ^ 4] 內
  • -10 ^ 5 <= Node.val <= 10 ^ 5

2 解題(Java)

題目解析

  1. 最適合連結串列的排序演算法是歸併排序。如果採用自頂向下的遞迴實現,則空間複雜度為O(log n),如果要達到O(1)的空間複雜度,則需要使用自底向上的實現方式;
  2. 首先求得連結串列的長度length,然後將連結串列拆分成子連結串列進行合併;
  3. 用subLength表示每次需要排序的子連結串列的長度,初始subLength=1;
  4. 每次將連結串列拆分成若干個長度為subLength的子連結串列(最後一個子連結串列的長度可以小於subLength),按照每兩個子連結串列一組進行合併,合併後即可得到若干個長度為subLength * 2的有序子連結串列(最後一個子連結串列的長度可以小於subLength * 2);
  5. 將subLength的值加倍,重複4,對更長的有序子連結串列進行合併操作,直到有序子連結串列的長度大於或等於length,整個連結串列排序完畢;

程式碼

/**
 * 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) { int length = 0; ListNode node = head; while (node != null) { node = node.next; length++; } ListNode dummyHead = new ListNode(0, head); for (int subLength = 1; subLength < length; subLength <<= 1) { ListNode prev = dummyHead, curr = dummyHead.next; while (curr != null) { ListNode head1 = curr; for (int i=1; i<subLength && curr.next != null; i++) { curr = curr.next; } ListNode head2 = curr.next; curr.next = null; curr = head2; for (int i = 1; i < subLength && curr != null && curr.next != null; i++) { curr = curr.next; } ListNode next = null; if (curr != null) { next = curr.next; curr.next = null; } ListNode merged = merge(head1, head2); prev.next = merged; while (prev.next != null) { prev = prev.next; } curr = next; } } return dummyHead.next; } public ListNode merge(ListNode head1, ListNode head2) { ListNode dummyHead = new ListNode(); ListNode temp = dummyHead; while (head1 != null && head2 != null) { if (head1.val <= head2.val) { temp.next = head1; head1 = head1.next; } else { temp.next = head2; head2 = head2.next; } temp = temp.next; } temp.next = head1 == null ? head2 : head1; return dummyHead.next; } }

3 複雜性分析

  • 時間複雜度O(nlogn):其中 n 是連結串列的長度;
  • 空間複雜度O(1)

來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/sort-list