找出陣列中前K個最小的數 Python實現

2021-09-25 18:47:11 字數 3310 閱讀 4587

尋找陣列中給定的第k大的數,或者前k個最大的數,與之同理,稍加改動即可
**如下
# 最大堆下沉調整,始終保持最大堆

def downadjust(ary_list, parent_index, length):

tmp = ary_list[parent_index]

child_index = 2 * parent_index + 1

while child_index < length:

if child_index + 1 < length and ary_list[child_index + 1] > ary_list[child_index]:

child_index += 1

if tmp >= ary_list[child_index]:

break

ary_list[parent_index] = ary_list[child_index]

parent_index = child_index

child_index = 2 * parent_index + 1

ary_list[parent_index] = tmp

pass

# 構建堆

def build_heap(ary_list, k):

index = k // 2 - 1 # 最後乙個非葉子結點

while index >= 0:

downadjust(ary_list, index, k)

index -= 1

pass

# 利用最大堆找出前k個最小值

# 每次從原陣列中拿出乙個元素和當前堆頂值比較,

# 然後判斷是否可以放入,放入後繼續調整堆結構

def heapk(ary, nums, k):

if nums <= k:

return nums

ks = ary[:k]

build_heap(ks, k) # 構建大頂堆(先不排序)

# print('build heap:', ks)

for index in range(k, nums):

ele = ary[index]

if ks[0] > ele:

ks[0] = ele

downadjust(ks, 0, k)

# print('heap adjust:', ks)

# 如果需要則輸出排序結果

# heap_sort(ks)

return ks

pass

if __name__ == '__main__':

# *** 測試方法1

ary_list = [10, 2, 38, 9, 22, 53, 47, 7, 3, 97]

nums = len(ary_list)

print('{} original data:'.format(nums), ary_list)

# # 原始陣列的排列順序(作為ks的對比)

# build_heap(ary_list, nums)

# heap_sort(ary_list)

# print('{} original sorted data:'.format(nums), ary_list)

for k in range(6, nums + 1):

ks = heapk(ary_list, nums, k)

print('{}th data:'.format(k), ks)

break

pass

結果如下圖所示:

如果想要輸出結果有序,則可以增加如下方法,進行堆排序即可。

# 堆排序(最大堆)

def heap_sort(ary):

length = len(ary)

index = length - 1

# 依次移除堆頂元素(放入末尾),並將末尾元素放在堆頂,進行下沉調整,

# 使得每次都會有非最大值上浮到堆頂,並重新調整為大頂堆;

# 然後再重複上述操作。

while index >= 0:

tmp = ary[0]

ary[0] = ary[index]

ary[index] = tmp

downadjust(ary, 0, index)

index -= 1

pass

針對二叉堆的思路,其實主要是尋找能容納k個元素的容器,然後在該容器中進行篩選操作。

若想要輸出有序結果,則可以選擇不同的排序演算法對k個元素進行排序即可。

時間複雜度

構建大頂堆:平均複雜度為o(klogk),;

元素篩選:剩餘n-k個元素,最壞情況下每個元素都要進行堆調整,複雜度為o((n-k)logk);

**如下:

# 類似於快排的思想,不同的地方在於每趟只需要往乙個方向走

# 按照從小到大的順序,尋找前k個最小值

時間複雜度:最壞情況下,每次只能找出乙個最小值,總共需要找k次,複雜度為o(kn);最好情況下只需要遍歷依次即可找到,複雜度為o(n);當k遠小於n時,平均時間複雜度為o(n)。

空間複雜度:因為開闢了儲存待尋找元素的陣列,所以空間複雜度為o(n)。

總結關於此型別問題,目前所總結和學習到的以這兩種方案為主,僅作分享。

若有錯漏,歡迎交流指正。

感謝~

找出陣列中第K個最小的數(快速排序)

問題描述 給定乙個無序的陣列,從乙個陣列中找出第k個最小的數,例如,對於給定陣列序列,其中第4小的數為5。演算法思路 採用快速排序,分而治之的思想,根據主元,每次partiton以主元為軸,比它小的數在左邊,比它大的數在右邊,判斷tmp的位置,如果它的位置為k 1,那麼它就是第k小的數,如果它的位置...

找出陣列中有多少組和小於k的三個數python版

給出乙個長度為n的陣列arr,和乙個數k,找出陣列中有多少組和小於k的三個數,即arr a arr b arr c 輸入 6 第一行為乙個整數n,代表輸入陣列的長度 2 0 1 2 3 6 第二行為n個整數 2 第三行為乙個整數k 輸出 4 乙個整數,表示有多少組滿足條件的三元組 import sy...

陣列中前k大的數

問題 程式設計之美 page139.尋找最大的k個數。方法一 通過全排序 快速排序 然後獲取前k個數即位最大的k個數。演算法複雜度 o nlogn 方法二 通過部分排序。選擇排序,氣泡排序 直接獲取前k個最大的數。演算法複雜度o n k 當k比較小的時候可以考慮 方法三 快速排序的變種。前面尋找陣列...