1. 利用快排的思想,由于每次只选择左右部分中的一部分,因此时间复杂度为O(n).
# -*- coding:utf-8 -*-
class Solution:
# (O(n)复杂度)
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
length = len(tinput)
if k == length:
return sorted(tinput)
if k <= 0 or k > length:
return []
start = 0
end = len(tinput) - 1
return self.quick_sort(tinput, start, end, k)
def quick_sort(self, ls, start, end, k):
if start <= end:
index1 = self.sort1(ls, start, end)
if index1 == k:
return sorted(ls[:k])
elif index1 < k:
return self.quick_sort(ls, index1+1, end, k)
else:
return self.quick_sort(ls, start, index1-1, k)
def sort1(self, ls, start, end):
i = start
j = end
base = ls[i]
while i < j:
while ls[j] > base and i < j:
j -= 1
if i < j:
ls[i] = ls[j]
i += 1
while ls[i] < base and i < j:
i += 1
if i < j:
ls[j] = ls[i]
j -= 1
ls[i] = base
return i
2. 堆排序,当元素个数小于k时,直接填入直到元素个数等于k时,对已有的k个元素进行堆排序形成最大堆(Ologk),接下来当元素个数大于k时,每次都将新元素与堆顶比较,若比堆顶还大,则不可能为最小的k个数,pass;若比堆顶元素小,则替换堆顶元素,并重新调整堆的顺序(Ologk).总时间复杂度为O(nlogk). 由于堆元素个数固定,适用于数组很大的情况,可减少内存占用。
# -*- coding:utf-8 -*-
class Solution:
# (O(n)复杂度)
def GetLeastNumbers_Solution(self, tinput, k):
length = len(tinput)
ls = []
if k == length:
return sorted(tinput)
if k > length or k < 1 or length <= 0:
return []
for i in range(length):
if i < k:
ls.append(tinput[i])
if i == k-1: # 此时正好k个元素,开始初始化最大堆
start = (0+i)//2
for j in range(start, -1, -1):
print(j)
self.heap_once(ls, j, k-1)
print(ls)
else:
if tinput[i] < ls[0]:
ls[0] = tinput[i]
self.heap_once(ls, 0, k-1)
else:
pass
return sorted(ls)
def heap_once(self, ls, start, end):
i = start
save = ls[start]
j = i*2+1
while j <= end:
print(j)
if j+1 <= end and ls[j+1] > ls[j]:
j += 1
if ls[i] < ls[j]:
ls[i], ls[j]= ls[j], ls[i]
i = j
j = 2*j+1
else:
break