-
Notifications
You must be signed in to change notification settings - Fork 0
Create Top_K_Frequent_Elements.md #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,105 @@ | ||||||||||||||||||
# 347. Top K Frequent Elements | ||||||||||||||||||
|
||||||||||||||||||
## 参考にした方々(Pythonで書かれた直近5名) | ||||||||||||||||||
- https://github.com/rinost081/LeetCode/pull/10/files | ||||||||||||||||||
- https://github.com/BumbuShoji/Leetcode/pull/10/files | ||||||||||||||||||
- https://github.com/t0hsumi/leetcode/pull/9/files | ||||||||||||||||||
- https://github.com/ichika0615/arai60/pull/7/files | ||||||||||||||||||
- https://github.com/olsen-blue/Arai60/pull/9/files | ||||||||||||||||||
|
||||||||||||||||||
## Step 1 | ||||||||||||||||||
### 考えたこと | ||||||||||||||||||
- 辞書を使いそう…だけど具体的にどうするかまで全くつながらなずギブアップ(getすら知らなかった…)、LeetCodeから答えをみて通るまで試す。 | ||||||||||||||||||
- [“for key, val”](https://docs.python.org/ja/3/tutorial/datastructures.html#looping-techniques)とかから使い慣れていないし、keyとvalをタプルにして一緒にheappushできるのも知らなかったしで、この辺の処理は今の自分からは絶対出てこないな…。 | ||||||||||||||||||
|
||||||||||||||||||
|
||||||||||||||||||
```Python | ||||||||||||||||||
class Solution: | ||||||||||||||||||
def topKFrequent(self, nums: List[int], k: int) -> List[int]: | ||||||||||||||||||
heap = [] | ||||||||||||||||||
counter = {} | ||||||||||||||||||
|
||||||||||||||||||
for num in nums: | ||||||||||||||||||
counter[num] = 1 + counter.get(num, 0) | ||||||||||||||||||
|
||||||||||||||||||
for key, val in counter.items(): | ||||||||||||||||||
heapq.heappush(heap, (-val, key)) | ||||||||||||||||||
|
||||||||||||||||||
res = [] | ||||||||||||||||||
while len(res) < k: | ||||||||||||||||||
res.append(heapq.heappop(heap)[1]) | ||||||||||||||||||
|
||||||||||||||||||
return res | ||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
## Step 2 | ||||||||||||||||||
### 学んだこと・思ったこと | ||||||||||||||||||
- 全く知らなかった操作もあったとはいえ、過去の問題に連想が行ったらrinostさんのstep1みたいなアプローチが出来たのか…。あの時辞書の操作がしっくりきておらず、結果として記憶に残らなかった感じがある。 | ||||||||||||||||||
- 全部理解できなくてもいいや精神で一度公式ドキュメント¶に目を通しとこう。 | ||||||||||||||||||
- Step1の回答にあった-1をかけてheappopした値をappendする方法より、heappopで頻度の小さい値を除外する方が手間が少なそう | ||||||||||||||||||
- Defaultdictを使うとキーの初期化なしで頻度を数えれるのか¶ | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. collection.Counterや setdefault()などいろいろな書き方があると思うのでそれらを考えても面白いかもしれません。 |
||||||||||||||||||
- 文字の種類がk以下な入力は確かにありそう。みんなValueErrorをいれてる。 | ||||||||||||||||||
- FYさんのステップ5が自然に頭に入ってきたのでこれをお手本にしたい | ||||||||||||||||||
- Step1で参照した回答ではheapという名前が使われてたけど、実際にはheapにはtop_k_hogeみたいな名前が似合うことが多い印象(これまで見てきたものがpopすることを見越してたからな気がする) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 自分が変数名にheapと入れていないのは、わざわざ numsをわざわざnums_listとしないくらいの気持ちです。 |
||||||||||||||||||
- ソート/セレクト周りのコードを読む元気がない(そもそもよく知らないのですごく工数がかかりそう…)ので余力がある時にまた…。 | ||||||||||||||||||
- 余談:PRを読んでいると、この辺の問題から公式ドキュメントを読みたい気持ちになっている方が他にもいらっしゃって面白い。更にできる人たちになると自力で色んな公式ドキュメントを連想できてい流のに加えて、関連するCPythonのコードを読み初めてる感じがある。この辺真似できるといいんだろうけれど、今のところ何が書いてあるか理解してコードを改良する&先人のPRやdiscordを引っ張ってくるのがやっとで、負荷的に真似できない。が、公式のドキュメントをチビチビ読むようになったのは進歩な気がする。 | ||||||||||||||||||
|
||||||||||||||||||
```Python | ||||||||||||||||||
class Solution: | ||||||||||||||||||
def topKFrequent(self, nums: List[int], k: int) -> List[int]: | ||||||||||||||||||
frequencies_of_appearance = defaultdict(int) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 出現回数を直訳したのだと思いますが、長いわりに何の出現回数か何のための変数かが伝わらないかと思います。 |
||||||||||||||||||
|
||||||||||||||||||
for num in nums: | ||||||||||||||||||
frequencies_of_appearance[num] += 1 | ||||||||||||||||||
|
||||||||||||||||||
if k > len(frequencies_of_appearance): | ||||||||||||||||||
raise ValueError("Fewer than k types of letters appear in nums") | ||||||||||||||||||
|
||||||||||||||||||
# 名前が長い... | ||||||||||||||||||
sorted_frequencies = sorted( | ||||||||||||||||||
frequencies_of_appearance, key=frequencies_of_appearance.get, reverse=True | ||||||||||||||||||
) | ||||||||||||||||||
Comment on lines
+59
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 横に長くなっているので、縦に並べるのも手かなと思います。
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||
|
||||||||||||||||||
top_k_elements = sorted_frequencies[:k] | ||||||||||||||||||
|
||||||||||||||||||
return top_k_elements | ||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
## Step 3 | ||||||||||||||||||
### コメント | ||||||||||||||||||
- 1回目: 5m 4s, 2回目:4m47s, 3回目:4m8s | ||||||||||||||||||
|
||||||||||||||||||
```Python | ||||||||||||||||||
class Solution: | ||||||||||||||||||
def topKFrequent(self, nums: List[int], k: int) -> List[int]: | ||||||||||||||||||
numbers_of_appearance = defaultdict(int) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 変数名を短くするなら num_to_counts とかでもいいかなと思いました。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同じ感覚です。辞書の変数名は「(キー)to(値)」というのが今の自分的にはしっくりきます。 |
||||||||||||||||||
|
||||||||||||||||||
for num in nums: | ||||||||||||||||||
numbers_of_appearance[num] += 1 | ||||||||||||||||||
|
||||||||||||||||||
if numbers_of_appearance < k: | ||||||||||||||||||
raise ValueError('Fewer types of letters appear in input nums') | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 例外処理を想定することは実務上は有益だと感じました。 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 戻ってきてから k 未満かを判定することもできますしね。 |
||||||||||||||||||
|
||||||||||||||||||
sorted_numbers_of_appearance = sorted(numbers_of_appearance, key=numbers_of_appearance.get, reverse=True) | ||||||||||||||||||
|
||||||||||||||||||
top_k_elements = sorted_numbers_of_appearance[:k] | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. こっちは return とくっつけてもいいかもしれません。 |
||||||||||||||||||
|
||||||||||||||||||
return top_k_elements | ||||||||||||||||||
``` | ||||||||||||||||||
|
||||||||||||||||||
## Step 4 | ||||||||||||||||||
時が経ったので復習がてら整理 | ||||||||||||||||||
```Python | ||||||||||||||||||
class Solution(object): | ||||||||||||||||||
def topKFrequent(self, nums, k): | ||||||||||||||||||
nums2counts = defaultdict(int) | ||||||||||||||||||
|
||||||||||||||||||
for num in nums: | ||||||||||||||||||
nums2counts[num] += 1 | ||||||||||||||||||
|
||||||||||||||||||
sorted_nums2counts = sorted(nums2counts, key=nums2counts.get, reverse=True) | ||||||||||||||||||
|
||||||||||||||||||
return sorted_nums2counts[:k] | ||||||||||||||||||
|
||||||||||||||||||
``` | ||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
私はこれ2行にしますね。
[1]が何なのか思い出す必要があるのと、目が左右に振られるので。
https://docs.google.com/document/d/11HV35ADPo9QxJOpJQ24FcZvtvioli770WWdZZDaLOfg/edit?tab=t.0#heading=h.kqo7dp4vlnzh
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
確かに解答を読んだ時に「これなんだっけな...」となりました。同様の書き方は避けようと思います。