1. 程式人生 > >【劍指offer】最小的k個數(兩種解法)

【劍指offer】最小的k個數(兩種解法)

題目描述
輸入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更優。