diff --git a/problems/347.top-k-frequent-elements/memo.md b/problems/347.top-k-frequent-elements/memo.md new file mode 100644 index 0000000..d9b8d97 --- /dev/null +++ b/problems/347.top-k-frequent-elements/memo.md @@ -0,0 +1,67 @@ +## step1 +- pythonのCounterでできないのか? +- Counter.most_common()でできそう +- https://github.com/python/cpython/blob/a8e814db96ebfeb1f58bc471edffde2176c0ae05/Lib/collections/__init__.py#L571 +- 内部で_heapq.nlargestを使っており、計算量はO(nlogk) + +```py +for num, _count in counter.most_common(): + frequent_nums.append(num) + if len(frequent_nums) == k: + break +``` +- 上記のように書いたが、forのindexをとるときは普段enumerateを使うようにしているが、今回の場合は下記のようになり少しわかりにくいかなと思って上記にした + +```py + for index, (num, _count) in enumerate(counter.most_common()): + frequent_nums.append(num) + if index == k - 1: + break + + return frequent_nums +``` + +## step2 +自分としては気になるところはないので、他の人のコードを見る +- https://github.com/Hiroto-Iizuka/coding_practice/pull/9/files + - Counterだと使うだけなので出題意図と沿っていないかも + - defaultdictに入れてvalueでkeyをsortして出すのも良いかも + - dictの命名は大抵の場合key_to_valueがわかりやすい!!! +- https://github.com/mamo3gr/arai60/pull/9/files + - コメント集のまとめが勉強になった + - コメント集をどのstepで読むか迷うがどこかでは読みたい + - `sorted(num_count, key=num_count.get)`の書き方は初めて見た。。。毎回lambda式を調べていた +- https://github.com/Yuto729/LeetCode_arai60/pull/15/files + - step2のheapのとこは文言で見ると難しそうでわかんなかった +- https://github.com/naoto-iwase/leetcode/pull/9/files + - 上のさっきのstep2解法だと思うが、見たらわかりやすかった + - 大きい順だと対応できないので-をつけてやる方法は`min-heap`という名前がついてるみたい + - `defaultdictではなく[Counter](https://docs.python.org/ja/3.13/library/collections.html#collections.Counter)のが適していそう。そう思う理由は今のところ、カウント用途に特化したクラスだから良さそう、というくらいしかない。` + - 自分は出現回数を数えるといえばと思ってほぼ何も考えず飛びついてしまったので何で適しているかは言語化していきたい + - クイックソートについて知っていなくてはいけないことは下記のようだが、計算量がO(NlogN)であることしか知らない。。。 + - 最悪・平均計算量 + - 末尾再帰最適化 + - ピボット選択 + - マージソートとのプロコン + - このかたのmemoはすごいが、自分の力量だとここまですると1問につき1年かかるので、1周したあとまた見にくる +- https://github.com/t-ooka/leetcode/pull/15/files + - たくさんの解法がおさえてありすごい + - いくつか自分も思いついた際は書けるようにしたい + +- defaultdictを使った解放にする + - 時間計算量はmをユニークな要素数としてO(n) + O(mlogm) + - 最悪時間計算量はO(nlogn)(ほぼmがnになるので) + - 空間計算量はO(m) + +## step3 +- defaultdictの初期値(今回はint)を忘れない +- key=~getの書き方はすっきりしているので毎回調べず書けるようになりたい + + + +## TODO +[] クイックソートについて + - 最悪・平均計算量 + - 末尾再帰最適化 + - ピボット選択 + - マージソートとのプロコン diff --git a/problems/347.top-k-frequent-elements/step1.py b/problems/347.top-k-frequent-elements/step1.py new file mode 100644 index 0000000..aa8c209 --- /dev/null +++ b/problems/347.top-k-frequent-elements/step1.py @@ -0,0 +1,23 @@ +# +# @lc app=leetcode id=347 lang=python3 +# +# [347] Top K Frequent Elements +# +from collections import Counter + + +# @lc code=start +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + counter = Counter(nums) + frequent_nums = [] + + for num, _count in counter.most_common(): + frequent_nums.append(num) + if len(frequent_nums) == k: + break + + return frequent_nums + + +# @lc code=end diff --git a/problems/347.top-k-frequent-elements/step2.py b/problems/347.top-k-frequent-elements/step2.py new file mode 100644 index 0000000..6a99b85 --- /dev/null +++ b/problems/347.top-k-frequent-elements/step2.py @@ -0,0 +1,24 @@ +# +# @lc app=leetcode id=347 lang=python3 +# +# [347] Top K Frequent Elements +# + +from collections import defaultdict + + +# @lc code=start +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + num_to_frequency = defaultdict(int) + for num in nums: + num_to_frequency[num] += 1 + + num_frequent_order = sorted( + num_to_frequency, key=num_to_frequency.get, reverse=True + ) + + return num_frequent_order[:k] + + +# @lc code=end diff --git a/problems/347.top-k-frequent-elements/step3.py b/problems/347.top-k-frequent-elements/step3.py new file mode 100644 index 0000000..797b0ef --- /dev/null +++ b/problems/347.top-k-frequent-elements/step3.py @@ -0,0 +1,24 @@ +# +# @lc app=leetcode id=347 lang=python3 +# +# [347] Top K Frequent Elements +# + +from collections import defaultdict + + +# @lc code=start +class Solution: + def topKFrequent(self, nums: List[int], k: int) -> List[int]: + num_to_frequency = defaultdict(int) + for num in nums: + num_to_frequency[num] += 1 + + num_frequency_order = sorted( + num_to_frequency, key=num_to_frequency.get, reverse=True + ) + + return num_frequency_order[:k] + + +# @lc code=end