1、题目描述
https://leetcode-cn.com/problems/sort-list/
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。
2、代码详解
2.1 归并排序(常用)
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if head == None or head.next == None:
return head
mid = self.getMid(head) # 用快慢指针分成两部分
# 找到左右部分
left = head
right = mid.next
# 把左部分最后置空
mid.next = None #
return self.merge(self.sortList(left), self.sortList(right)) # 合并
def merge(self, p1, p2):
dummy = ListNode(None)
cur = dummy
while p1 and p2:
if p1.val < p2.val:
cur.next = p1
p1 = p1.next
else:
cur.next = p2
p2 = p2.next
cur = cur.next
if p1 != None: # p1链有剩余
cur.next = p1
elif p2 != None: # p2链有剩余
cur.next = p2
return dummy.next
def getMid(self, node): # 获取链表的中间点
if not node:
return node
fast = node
slow = node
while fast.next and fast.next.next:
slow = slow.next
fast = fast.next.next
return slow
https://blog.csdn.net/qq_34364995/article/details/80994110
node1 = ListNode(4)
node2 = ListNode(2)
node3 = ListNode(1)
node4 = ListNode(3)
node1.next = node2
node2.next = node3
node3.next = node4
s = Solution()
print(s.sortList(node1).val)
2.2 快速排序
快速排序的最坏时间复杂度是 o(n*n),均摊复杂度才是 o(nlogn)。除非用 bfprt 等算法先进行轴心数选择,才可以降低最坏时间复杂度。
要求:期望平均时间复杂度为 O(nlogn),期望额外空间复杂度为 O(logn)。
思考题: 如果只能改变链表结构,不能修改每个节点的val值该如何做呢?
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head:
return head
# 分成三个链表,分别是比轴心head数小,相等,大的数组成的链表
big = None
small = None
equal = None
cur = head
while cur is not None:
t = cur
cur = cur.next
if t.val > head.val:
t.next = big # 将t接在big链表头部
big = t # 前移big指针,即更新头指针
elif t.val < head.val:
t.next = small
small = t
else:
t.next = equal
equal = t
# 拆完各自排序即可,equal 无需排序
big = self.sortList(big)
small = self.sortList(small)
ret = ListNode(None)
cur = ret
# 将三个链表组合成一起,这一步复杂度是 o(n)
for p in [small, equal, big]:
while p is not None:
cur.next = p
p = p.next
cur = cur.next
# cur.next = None
return ret.next