98. 链表排序
在 O(n log n) 时间复杂度和常数级的空间复杂度下给链表排序。
样例
给出 1->3->2->null
,给它排序变成 1->2->3->null
.
挑战
分别用归并排序和快速排序做一遍。
实现代码:
"""
Definition of ListNode
class ListNode(object):
def __init__(self, val, next=None):
self.val = val
self.next = next
"""
'''
#归并排序
class Solution:
"""
@param head: The head of linked list.
@return: You should return the head of the sorted linked list, using constant space complexity.
"""
def sortList(self, head):
# write your code here
if head is None or head.next is None:
return head
#找到链表的中点结点
mid = self.findMid(head)
#先执行链表中点往后
right = self.sortList(mid.next)
#将右半部分抛弃,则得到左半部分
mid.next = None
left = self.sortList(head)
return self.mergeTwoLists(left, right)
def findMid(self, head):
slow, fast = head, head.next
#slow移动一位, fast移动两位,当fast遍历完,slow正好处于中点
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
return slow
def mergeTwoLists(self, l1, l2):
# write your code here
dummy = ListNode(0)
tmp = dummy
while l1 != None and l2 != None:
if l1.val < l2.val:
tmp.next = l1
l1 = l1.next
else:
tmp.next = l2
l2 = l2.next
tmp = tmp.next
if l1 != None:
tmp.next = l1
elif l2 != None:
tmp.next = l2
return dummy.next
'''
'''
#快速排序
class Solution:
"""
@param head: The head of linked list.
@return: You should return the head of the sorted linked list, using constant space complexity.
"""
def sortList(self, head):
# write your code here
if head is None or head.next is None:
return head
mid = self.findMid(head)
leftDummy, rightDummy, midDummy = ListNode(0),ListNode(0),ListNode(0)
leftTail, rightTail, midTail = leftDummy, rightDummy, midDummy
while head:
#如果该结点的值小于中间结点的值,就加入左链表
if head.val < mid.val:
leftTail.next = head
leftTail = leftTail.next
#如果该结点的值大于中间结点的值,就加入右链表
elif head.val > mid.val:
rightTail.next = head
rightTail = head
#如果该结点的值等于于中间结点的值,就加入中间链表
else:
midTail.next = head
midTail = head
head = head.next
#链表的尾部指向None
leftTail.next, rightTail.next, midTail.next = None, None, None
#对左右链表开始递归
left = self.sortList(leftDummy.next)
right = self.sortList(rightDummy.next)
#合并三个链表
return self.concat(left, midDummy.next, right)
#找到链表的中点结点
def findMid(self, head):
slow, fast = head, head.next
#slow移动一位, fast移动两位,当fast遍历完,slow正好处于中点
while fast != None and fast.next != None:
fast = fast.next.next
slow = slow.next
return slow
#合并三个链表
def concat(self, left, mid, right):
dummy = ListNode(0)
tail = dummy
tail.next = left
#找到合并后链表的尾结点
tail = self.getTail(tail)
tail.next = mid
tail = self.getTail(tail)
tail.next = right
return dummy.next
#找到链表的尾结点
def getTail(self, head):
if head is None:
return None
while head.next:
head = head.next
return head
'''
#利用内置函数排序
class Solution:
"""
@param head: The head of linked list.
@return: You should return the head of the sorted linked list, using constant space complexity.
"""
def sortList(self, head):
# write your code here
from functools import cmp_to_key
nodes = []
while head:
nodes.append(ListNode(head.val))
head = head.next
dummy = ListNode(0)
node = dummy
for n in sorted(nodes, key=cmp_to_key(self.nodesort)):
node.next = n
node = node.next
return dummy.next
def nodesort(self, a, b):
return a.val - b.val