题目描述
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
- 你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
示例 2:
输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]
示例 3:
输入:head = []
输出:[]
提示:
- 链表中节点的数目在范围 [0, 5 * 104] 内
- -105 <= Node.val <= 105
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
归并排序,具体实现比较繁琐,注意细节,
官方题解
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
if(head == null)
return head;
ListNode tem = head;
int len = 0;
while(tem != null){
len++;
tem = tem.next;
}
ListNode preHead = new ListNode(0,head);
for(int i = 1;i < len;i<<=1){
ListNode cur = preHead.next,pre = preHead;
while(cur != null){
ListNode head1 = cur;
for(int j = 1;j < i && cur.next != null;++j){
cur = cur.next;
}
ListNode head2 = cur.next;
cur.next = null;
cur = head2;
for(int j = 1;j < i && cur != null && cur.next != null;++j){
cur = cur.next;
}
ListNode next = null;
if(cur != null){
next = cur.next;
cur.next = null;
}
ListNode merge = merge(head1,head2);
pre.next = merge;
while(pre.next != null){
pre = pre.next;
}
cur = next;
}
}
return preHead.next;
}
public ListNode merge(ListNode head1,ListNode head2){
ListNode head = new ListNode(-1);
ListNode cur1 = head1,cur2 = head2,tem = head;
while(cur1 != null && cur2 != null){
if(cur1.val < cur2.val){
tem.next = cur1;
cur1 = cur1.next;
}else{
tem.next = cur2;
cur2 = cur2.next;
}
tem = tem.next;
}
if(cur1 != null){
tem.next = cur1;
}else if(cur2 != null){
tem.next = cur2;
}
return head.next;
}
}