在O(n log n)时间复杂度和常数级的空间复杂度下给链表排序。
样例
给出 1->3->2->null
,给它排序变成 1->2->3->null
。
挑战
分别用归并排序和快速排序做一遍。
解题思路1:
快排。参考快速排序完美优化版
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The head of linked list.
* @return: You should return the head of the sorted linked list, using constant space complexity.
*/
public ListNode sortList(ListNode head) {
// write your code here
quickSort(head, null);
return head;
}
private void quickSort(ListNode left, ListNode right){
if(left == right)
return;
ListNode p = partition(left, right);
quickSort(left, p);
quickSort(p.next, right);
}
private ListNode partition(ListNode left, ListNode right){
int v = left.val;
ListNode j = left;
for(ListNode i=j.next; i != right; i = i.next){
if(i.val < v){
j = j.next;
swapValue(j, i);
}
}
swapValue(left, j);
return j;
}
private void swapValue(ListNode node1, ListNode node2){
int temp = node1.val;
node1.val = node2.val;
node2.val = temp;
}
}
解题思路2:
归并排序。先找出链表的中间节点,然后以此为界,将链表分为两部分,分别进行排序,最后将两部分排好序的链表归并即可。
/**
* Definition for ListNode
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param head: The head of linked list.
* @return: You should return the head of the sorted linked list, using constant space complexity.
*/
public ListNode sortList(ListNode head) {
// write your code here
if(head == null || head.next == null)
return head;
ListNode mid = getMid(head);
ListNode newHead = mid.next;
mid.next = null;
ListNode leftHead = sortList(head);
ListNode rightHead = sortList(newHead);
return merge(leftHead, rightHead);
}
//归并left与right两排序链表
private ListNode merge(ListNode left, ListNode right){
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while(left != null || right != null){
if(left != null && right != null){
if(left.val < right.val){
cur.next = left;
left = left.next;
}else{
cur.next = right;
right = right.next;
}
cur = cur.next;
}else if(left == null){
cur.next = right;
break;
}else{
cur.next = left;
break;
}
}
return dummy.next;
}
//获得以链表head的中间节点
private ListNode getMid(ListNode head){
if(head == null)
return null;
ListNode slow = head;
ListNode fast = head;
while(fast.next != null && fast.next.next != null){
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
}