LeetCode—148. Sort List
题目
要求将链表按需排列。对时间和空间有要求。
思路及解法
因为有时间和空间限制增加了难度。 的内平均时间复杂度排序算法只有三种,堆排序,快速排序和归并排序,但快速排序的最坏情况是 ,不能用。堆排序和归并排序的所有情况都是 。对于归并排序,我们知道需要 的空间复杂度,即需要一个临时数组来存放排好序的元素,显然也合理,但那是针对的是数组,对于链表,归并排序的空间复杂度为in-place sort,即不需要额外空间就可以完成。另外,归并排序还有一个比较好的优势是其稳定性。所以,对于本题的解法,我们首选归并排序。
这道题还是一个很好的题,可以回顾下归并排序,建议与归并排序一块看一看,再把递归好好想想。
代码
/**
* 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 || head.next==null) return head;
ListNode mid = getMiddleNode(head);
ListNode rightList = mid.next;
ListNode leftList = head;
mid.next = null;
return mergeList(sortList(leftList), sortList(rightList));
}
public ListNode mergeList(ListNode list1, ListNode list2){
ListNode dummy = new ListNode(0);
ListNode curr = dummy;
while(list1!=null && list2!=null){
if(list1.val<list2.val){
curr.next = list1;
list1 = list1.next;
}else{
curr.next = list2;
list2 = list2.next;
}
curr = curr.next;
}
curr.next = list1!=null ? list1 : list2;
return dummy.next;
}
public ListNode getMiddleNode(ListNode head){
ListNode slow = head, fast = head;
while(fast.next!=null && fast.next.next!=null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}