專題講解 手撕堆

2021-10-04 20:52:32 字數 2070 閱讀 5375

引入問題是leetcode347題,前k個高頻元素

堆性質:

class

solution

:def

topkfrequent

(self, nums: list[

int]

, k:

int)

-> list[

int]

:# hashmap 統計頻率

freq_count =

for num in nums:

if num in freq_count:

freq_count[num]+=1

else

: freq_count[num]=1

defsift_up

(arr, k)

:""" 時間複雜度 o(logk) k 為堆的規模"""

new_index, new_val = k-

1, arr[k-1]

while

(new_index >

0and arr[

(new_index-1)

//2][

1]> new_val[1]

):arr[new_index]

= arr[

(new_index-1)

//2] new_index =

(new_index-1)

//2arr[new_index]

= new_val # 這裡採用的是類似插入排序的賦值交換

defsift_down

(arr, root, k)

:""" o(logk). 左節點index 2*root+1, 右節點 2*root+2, 父節點 (child-1)//2"""

root_val = arr[root]

while(2

*root+

1< k)

: child =

2* root +

1# 小頂錐 用 >,大頂錐 用 <

if child+

1< k and arr[child][1

]> arr[child+1]

[1]:

child +=

1## 兩個子節點中小與根節點比較

if root_val[1]

> arr[child][1

]:arr[root]

= arr[child]

root = child # 繼續向下檢查

else

:break

# 如果到這裡沒亂序,不用再檢查後續子節點

## 新數值下沉到該位置

arr[root]

= root_val

# 注意構造規模為k的堆, 時間複雜度o(n),因為堆的規模是從0開始增長的

freq_list =

list

(freq_count.items())

# print(freq_list) [(1, 3), (2, 2), (3, 1)]第一項是key,第二項freq

## 採用小頂堆,確定了kk個以後,只要又大於堆頂的入堆,堆頂移除

min_heap =

for i in

range

(k):

) sift_up(min_heap, i+1)

# 遍歷剩下元素,大於堆頂入堆,下沉維護小頂堆

for item in freq_list[k:]:

priority = item[1]

if priority > min_heap[0]

[1]:

min_heap[0]

= item

sift_down(min_heap,

0, k)

return

[item[0]

for item in min_heap]

Python專題講解

python中的切片表示法 使用python實現乙個迴圈輸入 在python中複製乙個列表list 理解python的引數傳遞 理解python雙星和單星對引數的作用 理解python中的作用域規則 python中yield關鍵字的作用 在python中呼叫外部命令 if name main 的作用...

全面講解手推實戰之線性回歸

這個主題是講解機器學習,會全面的講解理論,知識乾貨。學了理論不會實踐怎麼辦?調了包不懂實現?每個演算法都會配備實踐,手推和簡單實現,讓你知其然,還要知其所以然。當然參考很多大佬的書,不舉例了,相信大家都知道。我可能不能完全的去講每乙個概念,一是我不想滿屏都是補充概念避免給剛學習的人第一反應知識體系太...

DDOS專題詳細講解

一 ddos進犯原理 ddos是英文distributed denial of service的縮寫,即 散布式拒絕效勞 ddos進犯原理大致分為以下三種 1.經過傳送大的資料報阻塞效勞器頻寬形成效勞器線路癱瘓 2.經過傳送特別的資料報形成效勞器tcp ip協議模組消耗cpu記憶體資源結尾癱瘓 3....