在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
来源:力扣(LeetCode)
思路
用归并排序的思路,首先用双指针法从中间节点把链表分成两部分(参考第876题),向下拆开;然后依次合并两个有序链表(参考第21题),向上合并。
class Solution {
public ListNode sortList(ListNode head) {
if(head==null||head.next==null)
return head;
//双指针法找到链表的中点位置
ListNode fast=head.next,slow=head;
while(fast!=null && fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode tmp=slow.next;
slow.next=null;//把链表从中点的位置截断
ListNode left=sortList(head);
ListNode right=sortList(tmp);
//接下来的问题转化为归并两个有序链表
ListNode dummy=new ListNode(0);
ListNode cur=dummy;
while(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;
}
cur.next=left!=null?left:right;
return dummy.next;
}
}