Skip to content

Commit beaeff2

Browse files
authored
Merge pull request #24 from colorbox/347
347. Top K Frequent Elements
2 parents df7a782 + 731e050 commit beaeff2

File tree

6 files changed

+231
-0
lines changed

6 files changed

+231
-0
lines changed

347/step1.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
20:14
3+
4+
Space: O(N)
5+
Time: O(NlogN)
6+
7+
出現頻度の高い順にk個の要素を返す。
8+
出現頻度をカウント、カウント部分を取り出してソートしてk個残す。
9+
残したカウントと合致する要素を使ってvector<int>を作成して返す。
10+
11+
*/
12+
class Solution {
13+
public:
14+
vector<int> topKFrequent(vector<int>& nums, int k) {
15+
map<int, int> counter;
16+
for (int num : nums) {
17+
if (!counter.contains(num)) {
18+
counter[num] = 0;
19+
}
20+
counter[num]++;
21+
}
22+
multiset<int> sorted_counts;
23+
for (auto pair : counter) {
24+
sorted_counts.insert(pair.second);
25+
}
26+
auto it = sorted_counts.begin();
27+
for (int i = 0; i < sorted_counts.size() - k; i++) {
28+
it++;
29+
}
30+
sorted_counts.erase(sorted_counts.begin(), it);
31+
32+
vector<int> answer;
33+
for (auto pair : counter) {
34+
if (sorted_counts.contains(pair.second)) {
35+
answer.push_back(pair.first);
36+
}
37+
}
38+
return answer;
39+
}
40+
};

347/step2_1.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public:
3+
vector<int> topKFrequent(vector<int>& nums, int k) {
4+
map<int, int> counter;
5+
for (auto num : nums) {
6+
if (!counter.contains(num)) {
7+
counter[num] = 0;
8+
}
9+
counter[num]++;
10+
}
11+
vector<int> heap;
12+
for (auto pair : counter) {
13+
heap.push_back(pair.second);
14+
push_heap(heap.begin(), heap.end(), std::greater<int>());
15+
if (heap.size() > k) {
16+
pop_heap(heap.begin(), heap.end(), std::greater<int>());
17+
heap.pop_back();
18+
}
19+
}
20+
set<int> top_nums;
21+
for (auto num : heap) {
22+
top_nums.insert(num);
23+
}
24+
vector<int> top_frequent_nums;
25+
for (auto pair : counter) {
26+
if (!top_nums.contains(pair.second)) {
27+
continue;
28+
}
29+
top_frequent_nums.push_back(pair.first);
30+
}
31+
return top_frequent_nums;
32+
}
33+
};

347/step2_2_.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
quick selectを利用する手法。
3+
*/
4+
class Solution {
5+
public:
6+
vector<int> topKFrequent(vector<int>& nums, int k) {
7+
map<int, int> frequent_counter;
8+
for (int num : nums) {
9+
if (!frequent_counter.contains(num)) {
10+
frequent_counter[num] = 0;
11+
}
12+
frequent_counter[num]++;
13+
}
14+
15+
vector<int> counts;
16+
for (auto pair : frequent_counter) {
17+
counts.push_back(pair.second);
18+
}
19+
20+
int kth_frequency_count = quick_select(counts, 0, counts.size() - 1, k);
21+
vector<int> top_k_frequency_nums;
22+
for (auto pair : frequent_counter) {
23+
if (pair.second < kth_frequency_count) {
24+
continue;
25+
}
26+
top_k_frequency_nums.push_back(pair.first);
27+
}
28+
29+
return top_k_frequency_nums;
30+
}
31+
32+
private:
33+
int partition(vector<int>& arr, int left, int right) {
34+
int pivot = right;
35+
int store_index = left;
36+
for (int i = left; i < right; i++) {
37+
if (arr[i] > arr[pivot]) {
38+
swap(arr[i], arr[store_index]);
39+
store_index++;
40+
}
41+
}
42+
swap(arr[store_index], arr[pivot]);
43+
return store_index;
44+
}
45+
46+
int quick_select(vector<int>& arr, int left, int right, int k) {
47+
int pivot = partition(arr, left, right);
48+
if (pivot == k - 1) {
49+
return arr[pivot];
50+
}
51+
if (pivot < k - 1) {
52+
return quick_select(arr, pivot + 1, right, k);
53+
}
54+
return quick_select(arr, left, pivot - 1, k);
55+
}
56+
};

347/step2_3.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
priority_queueで実装するパターンで解く
3+
*/
4+
class Solution {
5+
public:
6+
vector<int> topKFrequent(vector<int>& nums, int k) {
7+
map<int, int> frequency_counter;
8+
for (int num : nums) {
9+
if (!frequency_counter.contains(num)) {
10+
frequency_counter[num] = 0;
11+
}
12+
frequency_counter[num]++;
13+
}
14+
15+
priority_queue<pair<int, int>> frequency_queue;
16+
for (auto pair : frequency_counter) {
17+
frequency_queue.push(make_pair(pair.second, pair.first));
18+
}
19+
vector<int> top_k_frequent_nums;
20+
for (int i = 0; i < k; i++) {
21+
top_k_frequent_nums.push_back(frequency_queue.top().second);
22+
frequency_queue.pop();
23+
}
24+
25+
return top_k_frequent_nums;
26+
}
27+
};

347/step3.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
他の方のPRを見てprioority_queueの解法をベースに諸々を整えたパターンでstep3を実践
3+
*/
4+
class Solution {
5+
public:
6+
vector<int> topKFrequent(vector<int>& nums, int k) {
7+
map<int, int> num_to_count;
8+
for (int num : nums) {
9+
if (!num_to_count.contains(num)) {
10+
num_to_count[num] = 0;
11+
}
12+
num_to_count[num]++;
13+
}
14+
15+
priority_queue<NumCount> num_count;
16+
for (auto [num, count] : num_to_count) {
17+
num_count.push({num, count});
18+
}
19+
20+
vector<int> answer;
21+
for (int i = 0; i < k; i++) {
22+
answer.push_back(num_count.top().num);
23+
num_count.pop();
24+
}
25+
26+
return answer;
27+
}
28+
29+
private:
30+
struct NumCount {
31+
int num;
32+
int count;
33+
34+
bool operator< (const NumCount& other) const {
35+
return count < other.count;
36+
}
37+
};
38+
};

347/step4.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
priority_queueの最大サイズを制限する
3+
*/
4+
class Solution {
5+
public:
6+
vector<int> topKFrequent(vector<int>& nums, int k) {
7+
map<int, int> num_to_count;
8+
for (int num: nums) {
9+
num_to_count[num]++;
10+
}
11+
12+
priority_queue<NumCount, vector<NumCount>, greater<NumCount>> num_count;
13+
for (auto [num, count] : num_to_count) {
14+
num_count.push({num, count});
15+
if (num_count.size() > k) {
16+
num_count.pop();
17+
}
18+
}
19+
20+
vector<int> answer;
21+
for (int i = 0; i < k; i++) {
22+
answer.push_back(num_count.top().num);
23+
num_count.pop();
24+
}
25+
return answer;
26+
}
27+
28+
private:
29+
struct NumCount {
30+
int num;
31+
int count;
32+
33+
bool operator> (const NumCount& other) const {
34+
return count > other.count;
35+
}
36+
};
37+
};

0 commit comments

Comments
 (0)