题目描述
https://leetcode-cn.com/problems/sort-list/
思路
原来想的是用直接选择排序,每次从链表中找出最大的数来,加入到链表头部,结果时间超限,代码如下:
# 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: ListNode) -> ListNode:
#直接选择排序
if head==None: return None
f_head=front=low=ListNode(float("-inf"),next=head)
flag=True
while f_head.next:
maxx=float("-inf")
while front.next:
now=front.next
if now.val>maxx:
maxx=now.val
f=front
n=now
front=front.next
f.next=n.next
n.next=low.next
if flag==True:
f_head=n
front=f_head
flag=False
low.next=n
return low.next
于是看了下答案,改为归并排序,题解链接如下:
https://leetcode-cn.com/problems/sort-list/solution/pai-xu-lian-biao-by-leetcode-solution/
以4213为例,其过程如图所示:
代码如下:
class Solution:
def sortList(self, head: ListNode) -> ListNode:
def merge(head1: ListNode, head2: ListNode) -> ListNode:
dummyHead = ListNode(0)
temp, temp1, temp2 = dummyHead, head1, head2
while temp1 and temp2:
if temp1.val <= temp2.val:
temp.next = temp1
temp1 = temp1.next
else:
temp.next = temp2
temp2 = temp2.next
temp = temp.next
if temp1:
temp.next = temp1
elif temp2:
temp.next = temp2
return dummyHead.next
# 判断是否为空
if not head:
return head
#统计链表总长度
length = 0
node = head
while node:
length += 1
node = node.next
dummyHead = ListNode(0, head) #前哨指针
subLength = 1 #每次需要排序的长度,即归并长度
while subLength < length:
prev, curr = dummyHead, dummyHead.next
while curr:
head1 = curr
for i in range(1, subLength):
if curr.next:
curr = curr.next
else:
break
head2 = curr.next
curr.next = None
curr = head2
for i in range(1, subLength):
if curr and curr.next:
curr = curr.next
else:
break
#succ指向下一个需要连接的
succ = None
if curr:
succ = curr.next
curr.next = None
merged = merge(head1, head2)
#将断开的两个已经合并好的链接
prev.next = merged
#prev指向需要链接左边的链表的末尾
while prev.next:
prev = prev.next
curr = succ
subLength <<= 1
return dummyHead.next
思路new
https://leetcode-cn.com/problems/sort-list/solution/sort-list-gui-bing-pai-xu-lian-biao-by-jyd/
这个题解说的很清晰。分为自顶向下和自底向上两种。
代码如下:
【自顶向下】
# 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: ListNode) -> ListNode:
if head == None or head.next==None:return head
slow,fast=head,head.next#这里注意fast初始化为head.next,防止双数时slow为中心点的右边,导致无法对称切割
while fast and fast.next:
fast=fast.next.next
slow=slow.next
mid,slow.next=slow.next,None
left,right=self.sortList(head),self.sortList(mid)
h=res=ListNode(0)
while left and right:
if left.val<right.val:
h.next,left=left,left.next
else:
h.next,right=right,right.next
h=h.next
h.next=left or right
return res.next
【自底向上】
在这里插入代码片