在 O(n log n) 時間復雜度和常數級空間復雜度下,對鏈表進行排序。
示例 1:
輸入: 4->2->1->3
輸出: 1->2->3->4
示例 2:
輸入: -1->5->3->4->0 輸出: -1->0->3->4->5
按照題目要求,在O(n log n)時間復雜度下,首先想到七大排序中的歸並排序,因為快排的需要雙指針,指向首尾,單鏈表后一個元素沒有前一個元素指針。
思路:和歸並排序思路一樣,歸並思想不在此敘述,下面附上歸並排序鏈接:https://www.cnblogs.com/du001011/p/10520272.html
代碼如下:
/*
1.歸並排序思想
2.找到中間節點
3.進行歸並排序
*/
public static ListNode sortList(ListNode head) { return head == null ? head:mergeSort(head); } //歸並
private static ListNode mergeSort(ListNode head) { if (head.next == null) { return head; }
//快慢指針找出中間結點,這塊需要注意一點就是
//我們需要一個標記sign跟蹤慢結點,當找出中間結點時,
//讓中間結點前一結點即sign的下一個結點指向空
//這樣做的目的是為了使前半部分鏈表和后半部分鏈表進行合並排序
//慢結點 ListNode s = head;
//快結點 ListNode f = head;
//標記結點 ListNode sign = null; while (f.next != null) { sign = s; s = s.next; f = f.next.next; }
//標記結點下一個結點為空 sign.next = null; ListNode left = mergeSort(head); ListNode right = mergeSort(s); return merge(left, right); } //合並兩個鏈表
public static ListNode merge(ListNode l, ListNode r) { ListNode dummyHead = new ListNode(0); ListNode cur = dummyHead; while (l != null && r != null) { if (l.val <= r.val) { cur.next = l; cur = cur.next; l = l.next; } else { cur.next = r; cur = cur.next; r = r.next; } } if (l != null) { cur.next = l; } if (r != null) { cur.next = r; } return dummyHead.next; }