From 7c8c51d9b82aa240bd4a4b5ed8bb657ba137baf5 Mon Sep 17 00:00:00 2001 From: katataku Date: Mon, 25 Nov 2024 16:33:19 +0900 Subject: [PATCH] 703. Kth Largest Element in a Stream.md --- 703. Kth Largest Element in a Stream.md | 155 ++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 703. Kth Largest Element in a Stream.md diff --git a/703. Kth Largest Element in a Stream.md b/703. Kth Largest Element in a Stream.md new file mode 100644 index 0000000..38de0fa --- /dev/null +++ b/703. Kth Largest Element in a Stream.md @@ -0,0 +1,155 @@ +URL: https://leetcode.com/problems/kth-largest-element-in-a-stream/description/ + +# Step 1 + +- 実装時間: 15分 +- 時間計算量: + - init: O(nlog n) + - add: O(log n) +- 空間計算量: + - init: O(k) + - サイズkのヒープself.scores_heapのみを使用する。 + - add: O(1) + +```python +class KthLargest: + def __init__(self, k: int, nums: List[int]): + self.k = k + self.scores_heap = [] + for num in sorted(nums, reverse=True)[:k]: + heapq.heappush(self.scores_heap, num) + + def add(self, val: int) -> int: + if val <= self.scores_heap[0]: + return self.scores_heap[0] + heapq.heappop(self.scores_heap) + heapq.heappush(self.scores_heap, val) + return self.scores_heap[0] +``` + +与えられたscoreがk未満の状態でエラーになったので修正。 + +```python +class KthLargest: + def __init__(self, k: int, nums: List[int]): + self.k = k + self.scores_heap = [] + for num in sorted(nums, reverse=True)[:k]: + heapq.heappush(self.scores_heap, num) + + def add(self, val: int) -> int: + if len(self.scores_heap) == self.k and val <= self.scores_heap[0]: + return self.scores_heap[0] + if len(self.scores_heap) == self.k: + heapq.heappop(self.scores_heap) + heapq.heappush(self.scores_heap, val) + return self.scores_heap[0] +``` + +# Step 2 +- 参考にしたURL + - https://github.com/kazukiii/leetcode/pull/9 + - https://github.com/Yoshiki-Iwasa/Arai60/pull/7 + - https://github.com/seal-azarashi/leetcode/pull/8 + - https://github.com/haniwachann/leetcode/pull/1 + - https://github.com/tarinaihitori/leetcode/pull/8 + - https://github.com/hroc135/leetcode/pull/8 + - https://github.com/colorbox/leetcode/pull/23 + - https://github.com/SuperHotDogCat/coding-interview/pull/38 + - https://github.com/ryoooooory/LeetCode/pull/15 + - https://github.com/cheeseNA/leetcode/pull/12 + - https://github.com/goto-untrapped/Arai60/pull/23 + - https://github.com/Ryotaro25/leetcode_first60/pull/9 + +- initでもaddを呼ぶとシンプルになる。 + +- priority queueとheapの違い + - https://github.com/cheeseNA/leetcode/pull/12/files#r1543919411 + +- quick sortの常識 + - https://discord.com/channels/1084280443945353267/1200089668901937312/1203725416645271582 + - https://discord.com/channels/1084280443945353267/1183683738635346001/1185972070165782688 + +- 変数名 + - プライベート(とみなしたい)名前に`_`を足すルールは、プライベート関数だけだと間違えて理解してた。 + - 関数、メソッド、データ メンバーのいずれであっても同様。 + - https://docs.python.org/3/tutorial/classes.html#private-variables + +- `scores_heap`の変数名について + - 上位k番目までしか保持しないので、この名前だと全量持つような感じを与える。 + - 型の名前を不必要に変数名に含めない + - scores_heap + - `_kth_largest_nums`が良さそう + +- JavaのPriorityQueue + - push/pop/topがそれぞれoffer/poll/peekだと知った。名前が新鮮に感じた。 + - addは別にある。 + - https://docs.oracle.com/javase/8/docs/api/java/util/PriorityQueue.html + +- https://docs.python.org/3/howto/sorting.html + - 読んだ。 + - stableにするために、Decorate-Sort-Undecorateでindexを考慮する。 + - The Timsort algorithm used in Python + - 3.11から変わってる。 + - https://www.i-programmer.info/news/216-python/15954-python-now-uses-powersort.html + +- heappushpop + - >Push item on the heap, then pop and return the smallest item from the heap. The combined action runs more efficiently than heappush() followed by a separate call to heappop(). + - https://docs.python.org/3/library/heapq.html#heapq.heappushpop + +- > この問題で priority_queue にいきなりいくのは、私は実は違和感があります。 + - https://github.com/Ryotaro25/leetcode_first60/pull/9/files#r1619710596 + - > 平衡木は、どれも実装が大変なので、人生で一回書け、とまでは言い難いです。しかし、どれか一つくらいはどういうものであるか説明できるようにしておくといいんじゃないでしょうか。 + +- > priority queueは一度実装しておいたほうがよい。 + - https://discord.com/channels/1084280443945353267/1192736784354918470/1194613857046503444 + +- クイックセレクトについて + - quickソートで並び替えつつ、特定の位置の要素を確定させに行く。 + - > Quick Select も常識範囲 + - https://discord.com/channels/1084280443945353267/1183683738635346001/1186004009417449602 + +- kが負の場合について + - 今回は問題上、出てこない。 + - プラスアルファで検討しても良かった。弾くならinitで弾くべき + - https://github.com/tarinaihitori/leetcode/pull/8/files#r1815830919 + +```python +class KthLargest: + def __init__(self, k: int, nums: List[int]): + self._k = k + self._kth_largest_nums = [] + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + heapq.heappush(self._kth_largest_nums, val) + if len(self._kth_largest_nums) > self._k: + heapq.heappop(self._kth_largest_nums) + return self._kth_largest_nums[0] +``` + +# Step 3 + +- 時間計算量: + - init: O(nlog n) + - add: O(log n) +- 空間計算量: + - init: O(k) + - add: O(1) + +```python +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + self._k = k + self._kth_largest_nums = [] + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + heappush(self._kth_largest_nums, val) + if len(self._kth_largest_nums) > self._k: + heappop(self._kth_largest_nums) + return self._kth_largest_nums[0] +```