記事のディレクトリ
トピック:
空でない整数配列を指定すると、発生頻度が最も高い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 n)よりも優れている必要があります。ここでnは配列のサイズです。
- 質問データは、答えが一意であることを保証します。言い換えると、配列の最初のk個の高周波要素のセットが一意です。
- 回答は任意の順序で返すことができます。
解決策1:ヒープ
/**
* 思路:
* 统计词频在新的map上,k是数,v是词频
* heap中存放词频,统计前k个
*/
public int[] topKFrequent(int[] nums, int k) {
int[] res=new int[k];
HashMap<Integer, Integer> map = new HashMap<>();
PriorityQueue<Integer> heap = new PriorityQueue<>((v1, v2) -> map.get(v2) - map.get(v1));
for (int i:nums){
map.put(i,map.getOrDefault(i, 0)+1);
}
for(int key:map.keySet()){
heap.add(key);
}
for (int i=0;i<k;i++){
res[i]=heap.remove();
}
return res;
}
時間計算量:Onlogn
スペースの複雑さ:オン
解決策2:二分探索木
/**
* 思路:
* 二叉搜索树
* 统计词频在新的map上,k是数,v是词频
* TreeMap中存放,k是词频,v是数的集合
* 之后获取前k高词频的数
*/
public int[] topKFrequent(int[] nums, int k) {
int[] result = new int[k];
HashMap<Integer, Integer> map = new HashMap<>();
for(int i:nums){
map.put(i,map.getOrDefault(i,0)+1);
}
TreeMap<Integer, List<Integer>> bST = new TreeMap<>();
for (int num:map.keySet()){
Integer frequent = map.get(num);
if (!bST.containsKey(frequent)){
bST.put(frequent,new ArrayList());
}
bST.get(frequent).add(num);
}
List<Integer> list = new ArrayList<>();
while (list.size()<k){
list.addAll(bST.pollLastEntry().getValue());
}
for (int i=0;i<k;i++){
result[i]= list.get(i);
}
return result;
}
時間計算量:オン
スペースの複雑さ:オン