題目要求:在O(nlogn)的時間複雜度與常數空間複雜度對鏈表排序。
思路:歸併排序。
相關問題:如何快速確定鏈表的中間結點。
public ListNode sortList(ListNode head) {
if(head==null||head.next==null) return head;
//快慢指針拆分爲兩個鏈表
//這裏需要小小注意一下,書寫不正確會造成遞歸棧溢出
ListNode slow=head, fast=head.next;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode midHead=slow.next;
slow.next=null;
//分別排序,然後歸併
ListNode newHead1=sortList(head);
ListNode newHead2=sortList(midHead);
ListNode newHead=mergeList(newHead1,newHead2);
return newHead;
}
public ListNode mergeList(ListNode head1, ListNode head2){
ListNode p1=head1,p2=head2;
ListNode newHead,tail;
//先確立新的頭結點
if(p1.val<p2.val){
newHead=p1;
p1=p1.next;
}else{
newHead=p2;
p2=p2.next;
}
tail=newHead;
//比較&歸併
while(p1!=null&&p2!=null){
if(p1.val<p2.val){
tail.next=p1;
tail=tail.next;
p1=p1.next;
}else{
tail.next=p2;
tail=tail.next;
p2=p2.next;
}
}
if(p1!=null) tail.next=p1;
if(p2!=null) tail.next=p2;
return newHead;
}