题目:
Sort a linked list in O(n log n) time using constant space complexity.
分析:
时间复杂度nlogn,首先想到的是归并排序或快速排序
/**
* 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 smaller=new ListNode(0);
ListNode bigger=new ListNode(0);
//pres代表小,pre代表相等,preb代表大
ListNode pres=smaller;
ListNode pre=head;
ListNode preb=bigger;
//当前操作的节点
ListNode cur=head.next;
while(cur!=null){
//和当前head节点比较
if(cur.val<head.val){
pres.next=cur;
pres=pres.next;
}else if(cur.val>head.val){
preb.next=cur;
preb=preb.next;
}else{
//相等
pre.next=cur;
pre=pre.next;
}
cur=cur.next;
}
//分段结束后,将各段链表末尾置空,为后面拼接准备
pres.next=pre.next=preb.next=null;
//递归划分小的部分和大部分
smaller.next=sortList(smaller.next);
bigger.next=sortList(bigger.next);
//将三段链表拼接
//因为pres为smaller
//需要将pres置为最后
while(pres.next!=null){
pres=pres.next;
}
pres.next=head;
//bigger.next因为是bigger带头节点,所以需要取next
pre.next=bigger.next;
return smaller.next;
}
}
归并排序:
/**
* 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 fast=head,slow=head,pre=null;
while(fast!=null&&fast.next!=null){
pre=slow;
slow=slow.next;
fast=fast.next.next;
}
//分开
pre.next=null;
//递归划分两部分
ListNode h1=sortList(head);
ListNode h2=sortList(slow);
//合并
return merge(h1,h2);
}
//合并
public ListNode merge(ListNode l1,ListNode l2){
ListNode dummy=new ListNode(0);
ListNode cur=dummy;
//典型的合并思想
while(l1!=null&&l2!=null){
if(l1.val<l2.val){
cur.next=l1;
l1=l1.next;
}else{
cur.next=l2;
l2=l2.next;
}
cur=cur.next;
}
//防止还有元素
if(l1!=null)cur.next=l1;
if(l2!=null)cur.next=l2;
return dummy.next;
}
}