给你链表的头结点 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 = []
输出:[]
方法一:分治法
分:
将链表分为一个一个,通过递归实现。
治:
一个一个比较,小的排在前面,通过动态规划实现(比递归快了一倍)。
class Solution {
public ListNode sortList(ListNode head) {
return divide(head);
}
public ListNode divide(ListNode head) { //“分”方法
if(head == null || head.next == null)return head;
ListNode fast = head.next;
ListNode slow = head;
while(fast != null && fast.next != null){ //链表的中间值可以通过快慢指针实现
fast = fast.next.next;
slow = slow.next;
}
ListNode temp = slow.next;
slow.next = null;
ListNode left = divide(head);
ListNode right = divide(temp);
return merge(left,right);
}
public ListNode merge(ListNode left,ListNode right){ //“治”方法,这里使用动态规划比递归速度快了整整一倍
if(left == null)return right;
if(right == null)return left;
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;
}
if(left != null){
cur.next = left;
}else{
cur.next = right;
}
return dummy.next;
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-list