Skip to content

Commit 0cbfd6e

Browse files
Add top-k-frequent-elements
1 parent c0c9a12 commit 0cbfd6e

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
top-k-frequent-elements
3+
요구사항: 주어진 입력에 대해 k번째 빈도를 가지는 원소를 모두 반환하라.
4+
접근 1: 가장 단순한 접근법은 모든 원소에 대해 map으로 빈도를 세는 것입니다.
5+
ordered_map에서 삽입 비용은 자료구조 길이가 K일 때 O(logK)으로, N회 삽입 연산으로 O(NlogK) 인데,
6+
이때 모든 원소가 유일한 경우 K=N이므로 최악의 경우 O(NlogN) 입니다.
7+
그리고 정렬된 맵에서 k 위치를 찾는 lower_bound 연산 비용은 O(logN)으로, 총 O(NlogN)입니다.
8+
unordered_map은 삽입 비용이 O(1)이지만, N회 삽입 연산 이후, k를 찾기 위해 카운트를 정렬해야 한다는 점에서
9+
보편적인 정렬 비용 O(Nlog(N))이 발생합니다.
10+
접근 2: 총 비용이 O(NlogN)보다 낮아지려면 정렬 자료구조의 입력 비용이 O(logN)보다 낮거나,
11+
정렬 비용이 O(NlogN)보다 낮아야 합니다.
12+
한 가지 아이디어는 정렬 자료구조의 입력을 비용을 낮추는 필터 및 셋 기반 블랙리스트를 도입할 수 있다는 것입니다.
13+
- k초과 원소 필터: k보다 높은 빈도를 가지는 원소를 자료구조에서 제거 및 블랙리스트
14+
- k도달 불가 원소 필터: 현재 조회중인 입력에 대해 남은 원소의 수가 모두 해당 원소더라도 k에 미치지 못 하는 경우 제거 및 블랙리스트
15+
필터에 해당하는 원소가 M개일 때, 필터 비용은 해시셋 조회 O(1), 삽입 비용은 O(log(N-M))으로
16+
모든 입력에 대한 총 비용은 O(Nlog(N-M))입니다.
17+
접근 3: 우리가 원하는 것이 k 빈도 딱 하나라는 것을 고려하면, 해당 빈도를 키로 원소를 반환받는 구조를 생각해볼 수 있습니다.
18+
아이디어는 원소-카운팅맵으로 전체 입력에 대해 비용 O(N)으로 카운팅하고, 이를 바탕으로 카운팅-원소 해시맵으로 <빈도, 원소셋>을 빌드하는겁니다.
19+
해당 빌드 비용은 최대 N개 원소에 대해 조회+삽입 O(1) 이므로 O(N)입니다.
20+
필요한 정보는 카운팅-원소 해시맵으로 O(1) 조회합니다.
21+
*/
22+
23+
#include <vector>
24+
#include <unordered_map>
25+
#include <unordered_set>
26+
27+
class Solution {
28+
public:
29+
std::vector<int> topKFrequent(std::vector<int>& nums, int k) {
30+
std::unordered_map<int, int> elementCountMap;
31+
std::unordered_map<int, std::unordered_set<int>> countElementMap;
32+
std::vector<int> ans;
33+
34+
for(auto it = nums.begin(); it != nums.end(); it++) {
35+
int x = *it;
36+
elementCountMap[x]++;
37+
}
38+
39+
for(auto it = elementCountMap.begin(); it != elementCountMap.end(); it++) {
40+
int x = it->first;
41+
int count = it->second;
42+
countElementMap[count].insert(x);
43+
}
44+
45+
const std::unordered_set<int>& kFreqSet = countElementMap[k]; // avoid copy
46+
for(auto it = kFreqSet.begin(); it != kFreqSet.end(); it++) {
47+
int x = *it;
48+
ans.push_back(x);
49+
}
50+
return ans;
51+
}
52+
};

0 commit comments

Comments
 (0)