一、鏈表排序
1、歸並排序(遞歸版)
這個算法要采用遞歸,空間復雜度沒辦法達到O(n),時間復雜度為O(nlog(n)
# -*- coding: utf-8 -*-'
class ListNode(object):
def __init__(self, x):
self.val = x
self.next = None
class Solution(object):
def sortList(self, head):
if not head or not head.next:
return head
prev, slow, fast = None, head, head
while fast and fast.next:
prev, slow, fast = slow, slow.next, fast.next
prev.next = None # 將鏈表切斷,分為head和slow兩條子鏈
"""
等價以下代碼
l1 = self.sortList(head)
l2 = self.sortList(slow)
return self.merge(l1, l2)
"""
return self.merge(*map(self.sortList, (head, slow)))
def merge(self, l1, l2):
dummy = l = ListNode(None)
while l1 and l2:
if l1.val < l2.val:
l.next, l, l1 = l1, l1, l1.next
else:
l.next, l, l2 = l2, l2, l2.next
l.next = l1 or l2
"""
l1,l2長度不一樣時,l.next為l1,l2中比另一個長度長的子鏈
如 l1: 1->2 l2: 3->4->5, l.next為5
等價於以下代碼
if l1:
l.next = l1
else:
l.next = l2
"""
return dummy.next
if __name__ == "__main__":
s = Solution()
l = head = ListNode(None)
for val in [0, 4, 1, 6, 7]:
l.next = ListNode(val)
l = l.next
li = s.sortList(head.next)
while li:
print li.val
li = li.next
2、快速排序
這個算法比歸並排序復雜,速度比歸並排序快50%左右,但是沒看懂,以后再細細研究
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
def partition(start, end):
node = start.next.next
pivotPrev = start.next
pivotPrev.next = end
pivotPost = pivotPrev
while node != end:
temp = node.next
if node.val > pivotPrev.val:
node.next = pivotPost.next
pivotPost.next = node
elif node.val < pivotPrev.val:
node.next = start.next
start.next = node
else:
node.next = pivotPost.next
pivotPost.next = node
pivotPost = pivotPost.next
node = temp
return [pivotPrev, pivotPost]
def quicksort(start, end):
if start.next != end:
prev, post = partition(start, end)
quicksort(start, prev)
quicksort(post, end)
newHead = ListNode(0)
newHead.next = head
quicksort(newHead, None)
return newHead.next
3、投機取巧法(但是速度真的很快,leetcode打敗98.59%)
此算法比較取巧,使用一個列表臨時存儲鏈表中的值。
第一次遍歷鏈表,將鏈表中的值順序存儲到列表中,第二次遍歷鏈表,將排序后的列表的值放入鏈表中,時間復雜度為O(2n),空間復雜度應該為O(2n),時間復雜度為O(n)
class Solution(object):
def sortList(self, head):
"""
:type head: ListNode
:rtype: ListNode
"""
if not head or not head.next:
return head
temp = head
node_list = []
while head:
node_list.append(head.val)
head = head.next
node_list.sort()
head = temp
i = 0
while head:
head.val = node_list[i]
head = head.next
i += 1
return temp