尋找陣列中給定的第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比較小的時候可以考慮 方法三 快速排序的變種。前面尋找陣列...