147 问题描述:根据数组插入排序的思想实现链表的排序
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def insertionSortList(self, head: ListNode) -> ListNode:
# 首先设置一个虚拟结点p(过程当中会更新),cur从head开始向后走,指定一个val(即cur后面的数)。如果val前面的数即cur的值
# 都小于val,说明不用重排,cur继续向前走,如果val大于cur则从结点p(p随时更新,经过一次重排后,记录的是小于刚才重排
# 前val的最后一个值,或者说p后面一个数的值会大于重排前val)向后遍历,直到发现大于val,然后重排
# p也是在一直变化的,有时需要将其重置为虚拟节点,有时不需要
dummy = ListNode(-1)
dummy.next = head
p = dummy
cur = head
while cur and cur.next:
val = cur.next.val # 插入排序从第二个数开始循环,val即第二个数的值
if cur.val < val: # 默认val前都是排好序的,cur(val前面一个数)的值都小于val说明cur可以继续向后走
cur = cur.next
continue # 结束该步循环,直到发现cur的值大于val才不进入当前循环,进行下面的重排操作
if p.next.val > val: # 经过若干轮重排后,p可能走到中间某个位置,如果该位置下个数都小于val,p就不需要从dummy开始遍历,从当前位置遍历即可,即从下面while开始更改p的值,相反,p则要重新改成dummy,重头开始遍历
p = dummy
while p.next.val < val: # 当p.next的值大于val说明已经发现需要插入的位置了,可以结束循环
p = p.next # 当p.next的值小于val时,p需要继续向后走,直到找到需要插入的位置
new = cur.next # 重排过程
cur.next = new.next # 重排过程
new.next = p.next # 重排过程
p.next = new #重排过程
return dummy.next
148 问题描述:使用O(n log n)的时间复杂度对链表进行排序
解题思路:和数组中的归并排序相似。但在划分左右两边时有所不同。数组中左右两边大致均分。链表中先初始化一个slow=head,fast = head.next,然后每次fast向后走两步,slow向后走一步,因此slow和fast总是相隔一个中间的second。因此左边的数为从head到second(不包括second),右边为second(即右边的head)到最后一个数,然后进行重新排序。
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def sortList(self, head: ListNode) -> ListNode:
if not head or not head.next: #为空或只有一个数,则直接返回head
return head
# divide list into two parts
fast, slow = head.next, head
while fast and fast.next:
fast = fast.next.next
slow = slow.next
second = slow.next
# cut down the first part
slow.next = None
l = self.sortList(head)
r = self.sortList(second)
# return self.merge(l, r)
# # merge in-place without dummy node
# def merge(self, l, r):
if not l or not r:
return l or r
if l.val > r.val:
l, r = r, l
# get the return node "head"
head = pre = l
l = l.next
while l and r:
if l.val < r.val:
l = l.next
else:
nxt = pre.next
pre.next = r
tmp = r.next
r.next = nxt
r = tmp
pre = pre.next
# l and r at least one is None
pre.next = l or r
return head