一:LintCode 463 Sort Integers(用冒泡、选择、插入)
给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法。
class Solution:
def sortIntegers(self, A):
# write your code here
# ----------简单的冒泡排序,还有双向冒泡------------
# for i in range(len(A)):
# for j in range(1, len(A)):
# if A[j] < A[j-1]:
# A[j], A[j-1] = A[j-1], A[j]
# return A
# ----------选择排序------------------------------
# for i in range(len(A)):
# idx = i
# for j in range(i+1, len(A)):
# if A[j] < A[idx]: # 每一轮找最小值下标
# idx = j
# A[i], A[idx] = A[idx], A[i]
# return A
# ------------插入排序------------------------------
for i in range(1, len(A)+1):
for j in range(i-1, 0, -1): # 从后往年进行
if A[j-1] > A[j]:
A[j-1], A[j] = A[j], A[j-1]
else:
break
return A
二:LintCode 464. 整数排序 II(快排,归并,堆排序)
给一组整数,请将其在原地按照升序排序。使用归并排序,快速排序,堆排序或者任何其他 O(n log n) 的排序算法
归并和堆排序没有AC是因为我使用的不是原地排序,还有使用了库函数!
import heapq
class Solution:
def sortIntegers2(self, A):
# write your code here
# -------------------快速排序-------------------------------
# def quickSort(nums, left, right):
# if left >= right: return
# key = nums[left]
# i, j = left, right
# while i < j:
# while i < j and nums[j] >= key: j -= 1
# if i >= j: break
# nums[i] = nums[j]
# i += 1
# while i < j and nums[i] <= key: i += 1
# if i >= j: break
# nums[j] = nums[i]
# j -= 1
# nums[i] = key
# quickSort(nums, left, i-1)
# quickSort(nums, i+1, right)
# quickSort(A, 0, len(A)-1)
# ---------------归并排序------------------------------------
# def merge(left, right):
# s = []
# i = j = 0
# while i < len(left) and j < len(right):
# if left[i] <= right[j]:
# s.append(left[i])
# i += 1
# else:
# s.append(right[j])
# j += 1
# if i < len(left): s += left[i:]
# if j < len(right): s += right[j:]
# return s
# def mergeSort(nums):
# if len(nums) < 2: return nums
# mid = len(nums)//2
# left = mergeSort(nums[:mid])
# right = mergeSort(nums[mid:])
# return merge(left, right)
# mergeSort(A)
# ----------堆排序--------------------------------
heapq.heapify(A)
三:Leetcode 148. Sort List (链表的归并排序)
Sort a linked list in O(n log n) time using constant space complexity.
class Solution(object):
def sortList(self, head):
def merge(head1, head2): # 把两个链表合并成一个有序链表
newHead = ListNode(-1)
p = newHead
while head1 and head2:
if head1.val <= head2.val:
p.next = head1
p = p.next
head1 = head1.next
else:
p.next = head2
p = p.next
head2 = head2.next
if head1: p.next = head1
if head2: p.next = head2
return newHead.next
def mergeSort(head): # 使用快慢指针来切分链表
if not head or not head.next:
return head
slow = head
fast = head.next.next # 这里需要走两步
while fast and fast.next:
slow = slow.next
fast = fast.next.next
head2 = mergeSort(slow.next) # 下一段链表
slow.next = None # 断开链表
head3 = mergeSort(head) # 前一段链表
return merge(head2, head3)
return mergeSort(head)
四:Leetcode 23. Merge k Sorted Lists
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
- 暴力法: 时间:O(N) + O(NlogN) 空间:O(N) 最差情况
- 单个链表归并排序: 时间:O(N) + O(NlogN) 空间:O(1) 空间最优
- 优先队列或者最小堆:时间:O(N) + O(NlogK) 空间:O(N) 时间最优
- k个链表归并排序:时间:O(N) + O(NlogK) 空间:O(1) 时间空间都是最优
from Queue import PriorityQueue
class Solution(object):
def mergeKLists(self, lists):
# ---------暴力法----------------------------------------------
# 时间:O(N) + O(NlogN)
# 空间:O(N)
# self.nodes = []
# head = point = ListNode(0)
# for l in lists:
# while l:
# self.nodes.append(l.val)
# l = l.next
# for x in sorted(self.nodes): # 排序真好
# point.next = ListNode(x)
# point = point.next
# return head.next
# -----------归并排序(把所有链表先合成一个,Leetcode 148. Sort List)-------
# 时间:O(N) + O(NlogN) 还是不是最优的
# 空间:O(1)
# ---------优先队列或者最小堆------------------------------------------------
# 时间:O(N) + O(NlogK) 不是最优的情况啊,空间还可以优化
# 空间:O(N) + O(K)
# head = p = ListNode(-1)
# q = PriorityQueue()
# for L in lists: # 头结点
# if L: q.put((L.val, L)) # (k个链表头结点的值,头结点)
# while not q.empty():
# val, node = q.get() # 取出并弹出来
# p.next = ListNode(val)
# p = p.next
# node = node.next
# if node: q.put((node.val, node))
# return head.next
# ----------Merge with Divide And Conquer(升级的归并排序)-----------------------------
# 时间:O(NlogK) 还是最优的情况啊
# 空间:O(1)
def merge(head1, head2): # 合并两个链表,有空链表时也可以!
newHead = ListNode(-1)
p = newHead
while head1 and head2:
if head1.val <= head2.val:
p.next = head1
p = p.next
head1 = head1.next
else:
p.next = head2
p = p.next
head2 = head2.next
if head1: p.next = head1
if head2: p.next = head2
return newHead.next
n = len(lists)
if n < 1: return None
interval = 1
while interval < n:
for i in range(0, n-interval, interval*2): # 先两两合并
lists[i] = merge(lists[i], lists[i+interval])
interval *= 2 # 再四四合并,再八八合并
return lists[0]