148. 排序链表
在 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)
链接:https://leetcode-cn.com/problems/sort-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
结果:
代码:
class Solution {
public ListNode sortList(ListNode head) {
if(head == null){
return null;
}
//递归结束
if(head.next == null){
return head;
}
//快慢指针找中间节点
ListNode s = head;
ListNode f = head;
while(f.next != null && f.next.next != null){
s = s.next;
f = f.next.next;
}
//把链表从中间断开
ListNode tail = s;
s = s.next;
tail.next = null;
//对左链表递归并返回头指针
ListNode L = sortList(head);
//对右链表递归并返回头指针
ListNode R = sortList(s);
return merge(L, R);
}
//合并链表
public ListNode merge(ListNode left, ListNode right){
ListNode pre = new ListNode(-1);
ListNode cur = pre;
while(left != null && right != null){
if(left.val <= right.val){
cur.next = left;
cur = cur.next;
left = left.next;
}else{
cur.next = right;
cur = cur.next;
right = right.next;
}
}
cur.next = left == null ? right : left;
return pre.next;
}
}
思路:归并排序。还涉及了找链表的中间节点并断开链表,这一步可以用快慢指针获得,这时归并排序的分。归并的和则是将两个链表合成一条,创建一条新的链表cur,比较两条链表头节点大小,将小的节点加入到新的链表cur,直到其中一条链表空了,再把另一条链表加入新链表cur的尾部即可,这个在前几天做过。