题目
给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
示例 1:
输入:head = [4,2,1,3]
输出:[1,2,3,4]
代码
第一次使用朴素快速排序,基准值为头节点值,居然超时了,然后又改进成了随机基准的快排,以下是两个版本的代码
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def sortList(self, head: Optional[ListNode]) -> Optional[ListNode]:
return self.dfs(head)[0]
# 朴素快速排序
def dfs(self,head):
if(not head): return None,None
smaller_dummy = ListNode(-1)
smaller_node = smaller_dummy
bigger_dummy = ListNode(-1)
bigger_node = bigger_dummy
node = head.next
while(node):
if(node.val > head.val):
bigger_node.next = node
bigger_node = bigger_node.next
else:
smaller_node.next = node
smaller_node = smaller_node.next
node = node.next
smaller_node.next = None
bigger_node.next = None
smaller_head,smaller_tail = self.dfs(smaller_dummy.next)
bigger_head,bigger_tail = self.dfs(bigger_dummy.next)
if(smaller_head):
smaller_tail.next = head
head.next = bigger_head
return smaller_head,bigger_tail or head
else:
head.next = bigger_head
return head,bigger_tail or head
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def sortList(self, head):
return self.dfs(head)[0]
# 随机基准数的快排
def dfs(self,head,low=-100000,high=100000):
if(not head): return None,None
smaller_dummy = ListNode(-1)
smaller_node = smaller_dummy
bigger_dummy = ListNode(-1)
bigger_node = bigger_dummy
pivot_dummy = ListNode(-1)
pivot_node = pivot_dummy
node = head
pivot_num = random.randint(low, high)
while(node):
if(node.val > pivot_num):
bigger_node.next = node
bigger_node = bigger_node.next
elif(node.val < pivot_num):
smaller_node.next = node
smaller_node = smaller_node.next
else:
pivot_node.next = node
pivot_node = pivot_node.next
node = node.next
smaller_node.next = None
bigger_node.next = None
smaller_head,smaller_tail = self.dfs(smaller_dummy.next,low,pivot_num)
bigger_head,bigger_tail = self.dfs(bigger_dummy.next,pivot_num,high)
if(pivot_dummy.next):
if(smaller_head):
smaller_tail.next = pivot_dummy.next
else:
smaller_head = pivot_dummy.next
smaller_tail = pivot_node
if(smaller_tail): smaller_tail.next = bigger_head
return smaller_head or bigger_head,bigger_tail or smaller_tail