只有归并排序满足要求
public class Solution {
public ListNode findMiddle (ListNode head){
ListNode chaser = head;
ListNode runner = head.next;
while (runner!=null && runner.next!=null){
runner=runner.next.next;
chaser=chaser.next;
}
return chaser;
}
public ListNode mergeTwoList (ListNode p1,ListNode p2){
ListNode head=new ListNode(0);
ListNode dummy=head;
if (p1==null){
return p2;
}
if (p2==null){
return p1;
}
while (p1!=null && p2!=null){
if (p1.val<p2.val){
head.next=p1;
p1=p1.next;
}else{
head.next=p2;
p2=p2.next;
}
head=head.next;
}
if (p1==null){
head.next=p2;
}
if (p2==null){
head.next=p1;
}
return dummy.next;
}
public ListNode sortList(ListNode head) {
if (head==null || head.next==null){
return head;
}
ListNode mid= findMiddle(head);
ListNode right = sortList(mid.next);
mid.next=null;
ListNode left = sortList(head);
return mergeTwoList (left,right);
}
}
排序的过程:
①右递归,返回右链表头指针
②切断链表
③左递归,返回左链表头指针(这里要先右再左,操作比较方便)
④对左右链表做merge过程,返回头指针
merge过程:
即归并过程,左右链表谁的值小,粘上谁的结点,返回头指针
寻找中值过程:
快慢指针,快指针跑完,慢指针位置即中点
空间复杂度:明显为O(1)
时间复杂度分析:每次排序有一个findMiddle过程和一个merge过程,把两个过程分开看,都是O(nlogn)级别的,两者相加明显也是O(nlogn)