给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 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
进阶: 你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
解题思路
归并排序
首先讲一下本题的最优解,同时也是官方题解。
将原链表拆分为每一个节点为链表的子链表。
然后将它们两两合并,合并过程中会对比两个节点的大小,小的在前,大的在后。
再将合并后的子链表两两进行合并,同样,合并过程中,比较两个链表节点的大小,小的在前,大的在后。
直到所有子链表合并为一个链表,就完成了输入链表的排序。
因为每一个链表节点是一个对象,所以在整个拆分过程中是不会增加额外的存储空间的。\
代码实现
var sortList = function(head) {
// 特判输入链表为空,返回空
if(head === null) return null;
// 初始化数组存储链表中的节点值
const arr = [];
while(head){
arr.push(head.val);
head = head.next;
}
// 对节点值数组升序排序
arr.sort((a,b) => a-b)
// 根据排序数组构造结果链表
head = new ListNode(arr[0])
let cur = head;
for(let i = 1;i<arr.length;i++){
cur.next = new ListNode(arr[i])
cur = cur.next;
}
// 返回结果链表
return head;
};
至此我们就完成了 leetcode-148-排序链表