题目
Given the head of a linked list, return the list after sorting it in ascending order.
Follow up: Can you sort the linked list in O(n logn)
time and O(1)
memory (i.e. constant space)?
Example 1:
Input: head = [4,2,1,3]
Output: [1,2,3,4]
Example 2:
Input: head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]
Example 3:
Input: head = []
Output: []
Constraints:
The number of nodes in the list is in the range [0, 5 * 104]
.
-105 <= Node.val <= 105
解题思路
如果是数组,时间复杂度解法O(n logn)
比较多的选择,比如快速排序、分而治之再合并排序、堆排序等。但是在链表的世界里,只有分而治之的方法才是最快的。步骤如下:
- 找出中间节点,用单步和双步两个指针可以快速找出,并拆分为左边链表,右边链表;
- 递归调用继续拆分左边链表和右边链表,直到只有null或者只有一个节点为止;
- 逐个合并节点:定义结果空链表,对比合并的两个链表,小的值逐个拼接到结果链表中。
这种接法有个弊端,因为是递归,也就是会有栈溢出的风险。可以加个计数器,如果深度大于10,000 则抛出异常处理。
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class SortList:
def sortList(self, head: ListNode) -> ListNode:
if head == None or head.next == None:
return head
mid = self.getMid(head)
left = self.sortList(head)
right = self.sortList(mid)
return self.merge(left, right)
def merge(self, left: ListNode, right: ListNode) -> ListNode:
result = ListNode()
dummy = result
while left and right:
if left.val < right.val:
dummy.next = left
left = left.next
else:
dummy.next = right
right = right.next
dummy = dummy.next
if left:
dummy.next = left
if right:
dummy.next = right
return result.next
def getMid(self, head: ListNode) -> ListNode:
oneStep = None
while head and head.next:
if oneStep == None:
oneStep = head
else:
oneStep = oneStep.next
head = head.next.next
oneStepNext = oneStep.next
oneStep.next = None
return oneStepNext