排序链表
题目
给你链表的头结点 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 = []
输出:[]
解题思路
排序的题目且在时间复杂度为O(nlogn)下完成排序,则时间复杂度为O(nlogn)的排序算法有归并排序、快速排序(快速排序的最差时间复杂度为O(n^2))、堆排序,此题用归并排序最为合适。最容易想到的是自顶向下的递归实现,考虑递归调用的栈空间,自顶向下的归并排序需要O(nlogn)的空间复杂度,此题需要O(1)的空间复杂度,则需要自底向上的归并排序。自底向上的归并方法后面我再写。
归并排序(自上而下)
- 找到链表的中间节点并断开为两个子链表,此题找中间节点可用快慢指针方法,定义一个慢指针slow=head,快指针fast=head.next,慢指针走一步,快指针走两步,由于快指针走的距离是慢指针的两倍,故当快指针走到最后一个节点时,慢指针刚好走到中间节点,则mid=slow.next,再令slow.next=None,断开链表
- 对两个子链表分别排序(两个子链表同样再继续从中间断开,依次类推直到拆分为一个节点为止,然后再两两合并排序,最后结果则为两个有序链表)
- 对两个排序好的子链表进行合并排序,方法和合并两个有序链表方法一样
代码
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if (not head) or (not head.next):
return head
slow = head
fast = head.next
while fast and fast.next:
slow = slow.next
fast = fast.next.next
mid = slow.next
slow.next = None
return self.mergeList(self.sortList(head), self.sortList(mid))
def mergeList(self, node1, node2):
r = ListNode()
q = r
while node1 and node2:
if node1.val <= node2.val:
r.next = node1
node1 = node1.next
else:
r.next = node2
node2 = node2.next
r = r.next
r.next = node1 if node1 else node2
return q.next