LeetCodeEasy-【面試題40. 最小的k個數】topk 多種解法

輸入整數數組 arr ,找出其中最小的 k 個數。例如,輸入4、5、1、6、2、7、3、8這8個數字,則最小的4個數字是1、2、3、4。

示例 1:
輸入:arr = [3,2,1], k = 2
輸出:[1,2] 或者 [2,1]

示例 2:
輸入:arr = [0,1,2,1], k = 1
輸出:[0]

限制:
0 <= k <= arr.length <= 10000
0 <= arr[i] <= 10000

來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof
著作權歸領釦網絡所有。商業轉載請聯繫官方授權,非商業轉載請註明出處。

思路1:排序

需要最小的k個數,那麼只需要先排序,然後返回前k個數即可。
在這裏插入圖片描述

class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        arr.sort()
        return arr[:k]

思路2:堆

我們用一個大根堆實時維護數組的前 k小值。首先將前 k個數插入大根堆中,隨後從第 k+1個數開始遍歷,如果當前遍歷到的數比大根堆的堆頂的數要小,就把堆頂的數彈出,再插入當前遍歷到的數。最後將大根堆裏的數存入數組返回即可。在下面的代碼中,由於 C++ 語言中的堆(即優先隊列)爲大根堆,我們可以這麼做。而 Python 語言中的堆爲小根堆,因此我們要對數組中所有的數取其相反數,才能使用小根堆維護前 k 小值。
參考至Leetcode
這個數據全部取反,這個思路確實巧,直接將找k小變成了找k大,這樣就直接可以使用python中的heapq這個小根堆來做了,小根堆堆頂爲最小值,這樣我們每次和它比較,如果比他大就將其彈出,並將大的壓入。

class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        if k == 0 or arr == []:
            return []
        hp = [-a for a in arr[:k]]
        heapq.heapify(hp)
        for i in range(k, len(arr)):
            if -arr[i] > hp[0]:
            	# 先壓入,在彈出
                heapq.heappushpop(hp, -arr[i])
        return [-hp[i] for i in range(len(hp)-1, -1, -1)]

思路3:快排思想

在這裏插入圖片描述
快排

class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        if k == 0 or arr == []:
            return []
        def sort(left, right):
            if left >= right:
                return
            l = left
            r = right
            key = arr[left]  
            # 進行一次排序:  
            while l < r:
                while r > l and arr[r] >= key:
                    r -= 1
                while l < r and arr[l] <= key:
                    l += 1
                arr[l], arr[r] = arr[r], arr[l]
            arr[l], arr[left] = arr[left], arr[l]
            # 遞歸排序
            if k == l or k == l + 1:
                return
            elif k < l + 1:
                sort(left, l- 1) # 注意這裏上限是 l-1, 不是k-1
            else:
                sort(l + 1, right)
        sort(0, len(arr)-1)
        return arr[:k]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章