Question:
Sort a linked list in O(n log n) time using constant space complexity.
Analysis:
问题描述:在O(n log n)时间内用常数的空间复杂度,完成一个链表的排序。
思考:排序时间复杂度为O(n log n)的话,快排、堆排序、归并排序都是O(n log n),而冒泡排序、交换排序、选择排序都是O(n2),就这道题来讲,很容易相当应该使用归并排序。
之前做过一个题目合并两个已经排好序的链表,因此这里的思路是:递归+归并排序。每次将当前链表分成两部分,排序后合并成一个链表。(注意归并的结束条件)
Answer:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode sortList(ListNode head) { if(head == null || head.next == null) return head; ListNode slow = head, fast = head, firstList = head; while(fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } ListNode secondList = slow.next; slow.next = null; ListNode first = null, second = null; while(firstList != secondList) { first = sortList(firstList); second = sortList(secondList); return mergeTwoLists(first, second); } return mergeTwoLists(first, second); } public ListNode mergeTwoLists(ListNode l1, ListNode l2) { ListNode p1 = l1; ListNode p2 = l2; if(l1 == null && l2 == null) return null; if(l1 == null && l2 != null) return l2; if(l1 != null && l2 == null) return l1; ListNode fakeHead = new ListNode(0); ListNode p = fakeHead; while (p1 != null && p2 != null){ if (p1.val <= p2.val) { p.next = p1; p1 = p1.next; p = p.next; } else { p.next = p2; p2 = p2.next; p = p.next; } } if(p1 != null) p.next = p1; if(p2 != null) p.next = p2; return fakeHead.next; } }