diff --git a/347-Top-K-Frequent-Elements/note.md b/347-Top-K-Frequent-Elements/note.md
new file mode 100644
index 0000000..6210e58
--- /dev/null
+++ b/347-Top-K-Frequent-Elements/note.md
@@ -0,0 +1,35 @@
+# 347. Top K Frequent Elements
+
+
+
+## step1(まず通す)
+
+値→回数でカウントした後に回数→値の変換が高速にできて回数の大小でトータルオーダーのものが欲しいと思って Frequency を定義したけど冷静に考えると [回数, 値]のリストで良かった(List の順序は辞書順で判定)。
+
+nums の長さを n としたとき、時間計算量は
+
+- カウント部分が O(n)
+- ヒープ化が O(n)
+- 取り出すところが pop O(log n) をk 回で O(k log n)
+
+なので O(k * log n)
+
+空間計算量は長さ n か k の配列(中身は固定サイズ)をいくつか持っているのとあとは定数だけなので O(n)
+
+## step2(整形&他の人のコードを読む)
+
+ひとまずリストで書いてみた。
+
+-
+ - 自分が欲しかったものとして bidict というやつがあるらしい
+ -
+ - 自分の手でアルゴリズムを書かないとしたら Counter が便利
+ - 逆引き辞書を `{回数: [その回数出てきた値のリスト]}` で持っておけばバケットソートできて速そう
+ - クイックセレクトという、クイックソートの類似のアルゴリズムがあるらしい
+ - ヒープじゃなくてソートして先頭k個を取ってくるなら、`{値: 回数}` 辞書のまま value でソートするという方法があるらしい
+ -
+- heapq.heapify_max() などの max 系は 3.14 から使えるようになった新しい機能
+ -
+ - minheap しか使えないなら回数を符号反転で持つことで解決できる
+
+## step3(10分以内にさっとかける * 3回)
diff --git a/347-Top-K-Frequent-Elements/step1.py b/347-Top-K-Frequent-Elements/step1.py
new file mode 100644
index 0000000..2ab868a
--- /dev/null
+++ b/347-Top-K-Frequent-Elements/step1.py
@@ -0,0 +1,41 @@
+from functools import total_ordering
+from typing import Dict, List
+import heapq
+
+
+@total_ordering
+class Frequency:
+ def __init__(self, value: int, count: int):
+ self.value = value
+ self.count = count
+
+ def __eq__(self, other: object) -> bool:
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.count == other.count
+
+ def __lt__(self, other):
+ if not isinstance(other, self.__class__):
+ return NotImplemented
+ return self.count < other.count
+
+ def count_up(self):
+ self.count += 1
+
+
+class Solution:
+ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
+ frequency_counter: Dict[int, Frequency] = {}
+ for num in nums:
+ if frequency_counter.get(num) is None:
+ frequency_counter[num] = Frequency(num, 1)
+ else:
+ frequency_counter[num].count_up()
+
+ frequency_counts = list(frequency_counter.values())
+ heapq.heapify_max(frequency_counts)
+ k_most_frequent_elements = []
+ while len(k_most_frequent_elements) < k:
+ k_most_frequent_elements.append(heapq.heappop_max(frequency_counts).value)
+
+ return k_most_frequent_elements
diff --git a/347-Top-K-Frequent-Elements/step2.py b/347-Top-K-Frequent-Elements/step2.py
new file mode 100644
index 0000000..fe1781a
--- /dev/null
+++ b/347-Top-K-Frequent-Elements/step2.py
@@ -0,0 +1,20 @@
+from typing import Dict, List
+import heapq
+
+
+class Solution:
+ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
+ frequency_counter: Dict[int, List[int]] = {}
+ for num in nums:
+ if frequency_counter.get(num) is None:
+ frequency_counter[num] = [1, num]
+ else:
+ frequency_counter[num][0] += 1
+
+ frequency_counts = list(frequency_counter.values())
+ heapq.heapify_max(frequency_counts)
+ k_most_frequent_elements = []
+ while len(k_most_frequent_elements) < k:
+ k_most_frequent_elements.append(heapq.heappop_max(frequency_counts)[1])
+
+ return k_most_frequent_elements
diff --git a/347-Top-K-Frequent-Elements/step3.py b/347-Top-K-Frequent-Elements/step3.py
new file mode 100644
index 0000000..1f2d436
--- /dev/null
+++ b/347-Top-K-Frequent-Elements/step3.py
@@ -0,0 +1,20 @@
+from typing import Dict, List
+import heapq
+
+
+class Solution:
+ def topKFrequent(self, nums: List[int], k: int) -> List[int]:
+ # counter の value は [回数, 値]のリスト
+ counter: Dict[int, List[int]] = {}
+ for num in nums:
+ if counter.get(num) is None:
+ counter[num] = [1, num]
+ else:
+ counter[num][0] += 1
+
+ count_and_num = list(counter.values())
+ heapq.heapify_max(count_and_num)
+ top_k = []
+ while len(top_k) < k:
+ top_k.append(heapq.heappop_max(count_and_num)[1])
+ return top_k