347 前 K 個高頻元素

2021-10-22 16:07:41 字數 2897 閱讀 7705

快速排序法部落格:

給定乙個非空的整數陣列,返回其**現頻率前 k 高的元素。

示例 1:

輸入: nums = [1,1,1,2,2,3], k = 2

輸出: [1,2]

示例 2:

輸入: nums = [1], k = 1

輸出: [1]

思路與演算法

首先遍歷整個陣列,並使用雜湊表記錄每個數字出現的次數,並形成乙個「出現次數陣列」。找出原陣列的前 k 個高頻元素,就相當於找出「出現次數陣列」的前 k 大的值。

最簡單的做法是給「出現次數陣列」排序。但由於可能有 o(n) 個不同的出現次數(其中 n 為原陣列長度),故總的演算法複雜度會達到 o(n log n),不滿足題目的要求。

在這裡,我們可以利用堆的思想:建立乙個小頂堆,然後遍歷「出現次數陣列」:

遍歷完成後,堆中的元素就代表了「出現次數陣列」中前 k 大的值。

class

solution

// int 的第乙個元素代表陣列的值,第二個元素代表了該值出現的次數

priorityqueue<

int[

]> queue =

newpriorityqueue

<

int[

]>

(new

comparator

<

int[

]>()

});for

(map.entry

entry : occurrences.

entryset()

));}

}else);

}}int[

] ret =

newint

[k];

for(

int i =

0; i < k;

++i)

return ret;

}}

思路與演算法

我們可以使用基於快速排序的方法,求出「出現次數陣列」的前 k 大的值。

在對陣列 arr[l…r] 做快速排序的過程中,我們首先將陣列劃分為兩個部分 arr[i…q−1] 與 arr[q+1…j],並使得 arr[i…q−1] 中的每乙個值都不超過 arr[q],且 arr[q+1…j] 中的每乙個值都大於 arr[q]。

於是,我們根據 k 與左側子陣列 arr[i…q−1] 的長度(為 q−i)的大小關係:

class

solution

list<

int[

]> values =

newarraylist

<

int[

]>()

;for

(map.entry

entry : occurrences.

entryset()

));}

int[

] ret =

newint

[k];

qsort

(values,

0, values.

size()

-1, ret,

0, k)

;return ret;

}public

void

qsort

(list<

int[

]> values,

int start,

int end,

int[

] ret,

int retindex,

int k)

} collections.

swap

(values, start, index);if

(k <= index - start)

else

if(k > index - start +1)

}}}

總結:快速排序的這個方法沒看懂。官方的這個思路描述的實在是不像是人話,理解不明白。硬著頭皮一段一段思考**起碼還能稍微理解一下,看官方的文字描述是真的折磨。

還有乙個很好的思路。

最小堆法

思路:①借助雜湊表來建立數字及其出現頻次的對映

②維護乙個元素數目為k的最小堆

③每次都將新元素與堆頂元素(堆中頻率最小的元素)比較

④若新的元素比堆頂端的元素大,則彈出堆頂元素,將新元素新增進去

⑤最終,堆中k個元素即為前k個高頻元素

class

solution

else}}

//遍歷map,用優先佇列最小堆儲存頻率最大的k個元素

//建立小頂堆,若想建立大頂堆,則return map.get(b)-map.get(a)

/*繼承comparator介面,必須重寫compare 方法*/

priorityqueue

pq=newpriorityqueue

<

>

(new

comparator

()})

;//儲存頻率最大的k個元素,peek()方法:檢視堆頂元素值

for(integer key:map.

keyset()

)else

if(map.

get(key)

>map.

get(pq.

peek()

))}//取出最小堆的元素

list

res=

newarraylist

<

>()

;while

(!pq.

isempty()

)return res;

}

347 前K個高頻元素

給定乙個非空的整數陣列,返回其 現頻率前 k 高的元素。示例 1 輸入 nums 1,1,1,2,2,3 k 2 輸出 1,2 示例 2 輸入 nums 1 k 1 輸出 1 說明 你可以假設給定的 k 總是合理的,且 1 k 陣列中不相同的元素的個數。你的演算法的時間複雜度必須優於 o n log...

347 前 K 個高頻元素

維護乙個size是k的堆。求前k大的數,用小根堆 求前k小的數,用大根堆 求前k大,當堆的sizek時,去掉堆頂,最終堆中的資料就是最後的答案。如陣列arr 求最大的前3個數 一般來說求前k大 小,陣列中數是很大的,直接用排序,在選擇前k大 小的話,效率不高 首先建立堆,其size 0,一直push...

347 前 K 個高頻元素

方法很好想,要麼暴力排序,歸併,堆排都能滿足o nlogn 的要求。我第一次想到的就是,用雜湊統計一下數字,然後過載排一下序,順序放入集合裡就行。這次用的是最小堆,主要學習一下priorityqueue,是基於優先順序堆的無界優先順序queue modifier and type method an...