(LeetCode)148. Sort List
阿新 • • 發佈:2019-02-18
Sort a linked list in O(n log n) time using constant space complexity.
Example 1:
Input: 4->2->1->3 Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0 Output: -1->0->3->4->5
思路來源於評論區:
class Solution { public ListNode sortList(ListNode head) { if ( head == null || head.next == null) return head; ListNode preend = null; ListNode slow = head; ListNode fast = head; //將原連結串列分為兩個連結串列 while( fast != null && fast.next != null ) { preend = slow; slow = slow.next; fast = fast.next.next; } preend.next = null; //對兩個連結串列分別進行排序 ListNode l1 = sortList(head); ListNode l2 = sortList(slow); //將排序後的子連結串列歸併 return merge(l1, l2); } private ListNode merge(ListNode head1, ListNode head2) { ListNode helper = new ListNode(0); ListNode newhead = helper; while ( head1 != null && head2 != null ) { if ( head1.val <= head2.val ) { newhead.next = head1; newhead = newhead.next; head1 = head1.next; } else { newhead.next = head2; newhead = newhead.next; head2 = head2.next; } } newhead.next = head1 == null ? head2 : head1; return helper.next; } }
另一種解法:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode sortList(ListNode head) { if(head == null) return head; ListNode dummy = new ListNode(0); dummy.next = head; int n = 1; while(head.next != null) { head = head.next; n++; } for(int step = 1; step < n; step *= 2) { ListNode prev = dummy; ListNode cur = dummy.next; while(cur != null) { ListNode left = cur; ListNode right = split(left, step); cur = split(right, step); prev = merge(left, right, prev); } } return dummy.next; } private ListNode split(ListNode prev, int step) { if(prev == null) return prev; for(int i = 1; prev.next != null && i < step; i++) { prev = prev.next; } ListNode res = prev.next; prev.next = null; return res; } private ListNode merge(ListNode left, ListNode right, ListNode prev) { while(left != null && right != null) { if(left.val < right.val) { prev.next = left; left = left.next; } else { prev.next = right; right = right.next; } prev = prev.next; } if(left != null) prev.next = left; else if(right != null) prev.next = right; while(prev.next != null) prev = prev.next; return prev; } }