【劍指offer】最小的k個數(兩種解法)
阿新 • • 發佈:2018-11-28
題目描述
輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。
解法1
使用partition函式可以知道,使用==O(N)==的時間複雜度就可以找出第K大的數字,並且左邊的數字比這個數小,右邊的數字比這個數字大。因此可以取k為4,然後輸出前k個數字,如果需要排序的話再對結果進行排序
class Solution:
def PartitionOfK(self, numbers, start, end, k):
if k < 0 or numbers == [] or start < 0 or end >= len(numbers) or k > end:
return
low, high = start, end
key = numbers[low]
while low < high:
while low < high and numbers[high] >= key:
high -= 1
numbers[low] = numbers[high]
while low < high and numbers[low] <= key:
low += 1
numbers[high] = numbers[low]
numbers[low] = key
if low < k:
self.PartitionOfK(numbers, start + 1, end, k)
elif low > k:
self.PartitionOfK(numbers, start, end - 1, k)
def GetLeastNumbers_Solution (self, tinput, k):
# write code here
if k <= 0 or tinput == [] or k > len(tinput):
return []
self.PartitionOfK(tinput, 0, len(tinput) - 1, k)
return sorted(tinput[0:k])
執行時間:30ms
佔用記憶體:5732k
解法2
解法1存在兩個問題,一個是partition把陣列的順序改變了,第二是無法處理海量的資料,海量的陣列全部匯入到記憶體裡面做partition顯然是不合適的。因此可以找出結果中最大的數字,如果遍歷的數字比這個數字小,則替換,否則不變,可以採用堆的形式來實現資料結構,達到O(logK)的複雜度,因此整體的時間複雜度為N*O(logK)
class Solution:
def GetLeastNumbers_Solution(self, tinput, k):
# write code here
if tinput == [] or k <= 0 or k > len(tinput):
return []
result = []
for num in tinput:
if len(result) < k:
result.append(num)
else:
if num < max(result):
result[result.index(max(result))] = num
return sorted(result)
執行時間:25ms
佔用記憶體:5724k
時間和空間佔用都比解法1更優。