Conversation
| self.heapifyed_values = nums | ||
| heapq.heapify(self.heapifyed_values) |
There was a problem hiding this comment.
heapq.heapify() は引数をヒープ構造を満たすように in-place で変換するそうなので、もとの nums を変更しそうです。
https://docs.python.org/3.11/library/heapq.html#heapq.heapify
Transform list x into a heap, in-place, in linear time.
| class KthLargest: | ||
| def __init__(self, k: int, nums: List[int]): | ||
| self.k = k | ||
| self.top_k_values = [] |
There was a problem hiding this comment.
今回のケースでは問題になりませんが、必ずしもソートされているわけではないので変数名がミスリーディングさせる可能性がありそうです(私もこう書いていたのですが…)。
| ## step1 | ||
| - 二分探索木みたいなのに追加していって調べるのがいいのか? | ||
| - 普通のリストだと追加が遅いと思った | ||
| - 計算量がだいぶうろ覚え |
There was a problem hiding this comment.
もし計算量を覚えようとしたということであれば、仕組みから導出できるようにもしたほうが良いかもしれません。そのほうが覚える量が少なくて済み、脳にやさしいかもしれません。
二分探索木は、子要素を辿っていくたびに、探索対象となるノードの数が半分になります。 2(探索回数) ≒ (ノード数) ですので、(探索回数) = log2(ノード数) で O(log N) になります。また、この考え方以外にも同様の考え方があると思います。ご自身にとって考えやすい考え方で理解し、忘れたときにも導出できるようにすることをおすすめします。
類題: 三角形の内角の和は何度ですか?また、その証明を導出できますか?
| - 今回の問題ではNと比較してKが小さいとかないので上位のみでカットする方法は最悪計算量は変わらなさそう | ||
| - 遅くなりことはおそらくないのでやれるならやった方が良い? | ||
| - 最小値の取得はheap[0] (最小値の取得): O(1)で行えるのでそこで早くなる(step2-2) | ||
| - これで劇的に早くなった26ms(メモリは25.71MB) |
There was a problem hiding this comment.
この 26ms は LeetCode 上での実行時間でしょうか?
LeetCode の実行時間は誤差が大きいようですので、あまり信用しないほうが良いと思います。もし実行時間を知りたい場合は、自身でマイクロベンチマークを作り、ローカルの環境で計測数ることをお勧めいたします。
| def _trim_to_top_k(self): | ||
| while len(self.heapifyed_values) > self.k: | ||
| heapq.heappop(self.heapifyed_values) |
There was a problem hiding this comment.
関数に切り出すのいいですね。私の感覚、これくらいが切り出すか切り出さないかの境界くらいです。
問題
https://leetcode.com/problems/kth-largest-element-in-a-stream/
次に解く問題
Top k frequent elements