题目:
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
进阶:
你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?
示例:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
思路:
递归,归并排序
按照题目时间复杂度的要求,可以使用归并排序将链表按照升序排列,归并排序实现的整体思路是先将链表分成两半,然后对左右两半部分分别递归进行归并排序,最后将递归排序好的两部分按照归并排序合并在一起,最后输出合并后的链表。
具体过程是
传入链表头节点,通过快慢指针的方法将链表分成两部分,这里要记得将链表前半部分的最后一个节点保留,即pre,然后让这个节点连接空,分成两个链表。如果pre为空就说明只有一个节点了,返回这个节点,开始最内层的合并,比较两个节点的大小进行排序,返回连接好的链表。
当左右两个链表都实现了归并以后,进行合并的过程是创建一个虚拟头节点,连接后面的节点,对于两个链表,不断的选择值小的节点连接到后面,移动左右两部分的链表指针和输出链表的指针,直到其中一个链表为空,跳出循环,最后连接上非空的链表,输出排序后的链表。
时间复杂度满足要求,空间复杂度是O(n)。
# Definition for singly-linked list.
# 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:
return head
if head:
fast = slow = head
pre = None
while fast and fast.next:
pre = slow
fast = fast.next.next
slow = slow.next
if not pre:
return head # 即只有一个节点
pre.next = None # 分成了两个链表
left = self.sortList(head)
right = self.sortList(slow)
dummy = p = ListNode(0)
while left and right: # 都非空
if left.val < right.val:
p.next = left
left = left.next
else:
p.next = right
right = right.next
p = p.next
if left:
p.next = left
if right:
p.next = right
return dummy.next