题目
Sort a linked list in O ( n log n ) time using constant space complexity.
思路
1 看到排序,脑中各种算法。因为时间复杂度,马上想到mergesort 和 quicksort。
2 如果没有空间复杂度所限,只要有一个map,map'key就是链表的val值,map’val 是链表的节点;遍历一遍存储到map,在按照map的key值从大到小链接节点就好了。
3 考虑mergesort,关键是用多少的参数来递归?一开始感觉需要pre,post,head还需要链表的数量,可是这样一来链接的顺序就很复杂了。
4 这时候,如果有思路,考虑到把当中截断,中间节点之后为null。这样就不需要考虑pre和post的情况。而且代码也和一般的merge一样简洁。
5 当然其实链表数量也不需要了,只需要判断是否到null即可。所以说这个改变是个一劳永逸的方法。
代码
public class Solution {
public ListNode sortList(ListNode head) {
if(head == null){
return null;
}
ListNode cur = head;
int n =0;
while(cur!=null){
cur = cur.next;
n++;
}
return MergeSort(head,n);
}
public ListNode MergeSort(ListNode head, int n){
if(n<=1){
return head;
}
ListNode cur = head;
int i=1;
while(i<n/2){
cur=cur.next;
i++;
}
ListNode nexthead = cur.next;
cur.next = null;
ListNode head1 = MergeSort(head ,n/2);
ListNode head2 = MergeSort(nexthead,n-n/2);
ListNode dummy = new ListNode(Integer.MIN_VALUE);
cur = dummy;
ListNode cur1 = head1;
ListNode cur2 = head2;
int l1 = 0;
int l2 = 0;
while(l1<n/2 && l2<(n-n/2)){
if(cur1.val<=cur2.val){
cur.next = cur1;
cur1 = cur1.next;
l1++;
}
else{
cur.next = cur2;
cur2 = cur2.next;
l2++;
}
cur = cur.next;
}
if(l1<n/2){
cur.next = cur1;
}
else{
cur.next = cur2;
}
return dummy.next;
}
}