From 7f822331a633784a3c547de9335713569a319c8d Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 6 Jul 2024 16:28:34 +0900 Subject: [PATCH 1/4] phase1 --- .../kth_largest_element_in_a_stream/phase1.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 arai60/kth_largest_element_in_a_stream/phase1.py diff --git a/arai60/kth_largest_element_in_a_stream/phase1.py b/arai60/kth_largest_element_in_a_stream/phase1.py new file mode 100644 index 0000000..ed03382 --- /dev/null +++ b/arai60/kth_largest_element_in_a_stream/phase1.py @@ -0,0 +1,21 @@ +# 普通に苦戦した +# 思考録: Quick selectアルゴリズムを思いつく, だが動的に配列が変化するので無駄に計算が増え, 他に効率が良いものがないか考える +# じゃあdequeでmax_len=kを指定してやれば良いかなと思ったが, これだと結局途中に要素を挿入するときに時間計算量がO(k)程度かかるので断念 +# 要素数をkに保ったmin_heapのrootを出力する方向で制作, これなら挿入操作もO(logk)程度で良い +# heapqを覚えていなかったのでhttps://docs.python.org/ja/3/library/heapq.htmlを確認した。 +# heapq.heapreplaceかheapq.heappushpopのどちらを使うか迷う。前者はpopしてからpush, 後者はpushしてからpopでどちらも要素数は保存されるのでどちらでも良いかなと思ったが... +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + self.min_heap = [] # min_heap has k elements and min_heap[0] means the k-th largest element in the stream + self.k = k + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + if len(self.min_heap) < self.k: + heapq.heappush(self.min_heap, val) + elif val > self.min_heap[0]: + heapq.heappushpop(self.min_heap, val) + + return self.min_heap[0] From 257ceee4b711bc46ecd43cb6710357ccf9888fb8 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 6 Jul 2024 16:28:40 +0900 Subject: [PATCH 2/4] phase2 --- .../kth_largest_element_in_a_stream/phase2.py | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 arai60/kth_largest_element_in_a_stream/phase2.py diff --git a/arai60/kth_largest_element_in_a_stream/phase2.py b/arai60/kth_largest_element_in_a_stream/phase2.py new file mode 100644 index 0000000..05dc4f1 --- /dev/null +++ b/arai60/kth_largest_element_in_a_stream/phase2.py @@ -0,0 +1,45 @@ +""" +Reference: +ryoooooory: https://github.com/ryoooooory/LeetCode/pull/15/files +seal-azarashi: https://github.com/seal-azarashi/leetcode/pull/8#pullrequestreview-2153924472 +Yoshiki-Iwasa: https://github.com/Yoshiki-Iwasa/Arai60/pull/7 +kazukiii: https://github.com/kazukiii/leetcode/pull/9/files +hayashi-ay: https://github.com/hayashi-ay/leetcode/pull/54/files +cheeseNA: https://github.com/cheeseNA/leetcode/pull/12/files + +add method以外でmin_heap propertyをいじって欲しくないのでアンダーバーをつけてprivateであることを主張して書くべきだと感じた +ryooooooryさんのコメントにあった: 順次追加処理かつソート操作に強いPriorityQueueで実装とあったので少し頭の片隅にいれておく + +""" +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + self._min_heap = [] # _min_heap has k elements and _min_heap[0] means the k-th largest element in the stream + self.k = k + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + if len(self._min_heap) < self.k: + heapq.heappush(self._min_heap, val) + elif val > self._min_heap[0]: + heapq.heappushpop(self._min_heap, val) + + return self._min_heap[0] + +# 別のheapq実装もためす。https://docs.python.org/ja/3/library/heapq.htmlにはheappushpopを使った方が1回ずつpushとpopを呼び出すよりも効率が良いので, 上の方が良い? +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + self._min_heap = [] # _min_heap has k elements and _min_heap[0] means the k-th largest element in the stream + self.k = k + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + # Add new value and pop until len(self._min_heap) == self.k + heapq.heappush(self._min_heap, val) + while len(self._min_heap) > self.k: + heapq.heappop(self._min_heap) + + return self._min_heap[0] From 579534b29ecde5af0e7aa0ba426fd19db3ff2bfa Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 6 Jul 2024 16:28:49 +0900 Subject: [PATCH 3/4] phase3 --- arai60/kth_largest_element_in_a_stream/phase3.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 arai60/kth_largest_element_in_a_stream/phase3.py diff --git a/arai60/kth_largest_element_in_a_stream/phase3.py b/arai60/kth_largest_element_in_a_stream/phase3.py new file mode 100644 index 0000000..6e5c1fa --- /dev/null +++ b/arai60/kth_largest_element_in_a_stream/phase3.py @@ -0,0 +1,15 @@ +class KthLargest: + + def __init__(self, k: int, nums: List[int]): + self._min_heap = [] # _min_heap has k elements and _min_heap[0] means the k-th largest element in the stream. + self.k = k + for num in nums: + self.add(num) + + def add(self, val: int) -> int: + if len(self._min_heap) < self.k: + heappush(self._min_heap, val) + elif val >= self._min_heap[0]: + heappushpop(self._min_heap, val) + + return self._min_heap[0] \ No newline at end of file From 91c707fee33eba4fb9482137ce9fd9c65f130544 Mon Sep 17 00:00:00 2001 From: SuperHotDogCat Date: Sat, 6 Jul 2024 16:29:18 +0900 Subject: [PATCH 4/4] =?UTF-8?q?phase3=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E6=9C=AB=E5=B0=BE=E6=94=B9=E8=A1=8C=E5=BF=98=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arai60/kth_largest_element_in_a_stream/phase3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arai60/kth_largest_element_in_a_stream/phase3.py b/arai60/kth_largest_element_in_a_stream/phase3.py index 6e5c1fa..546732c 100644 --- a/arai60/kth_largest_element_in_a_stream/phase3.py +++ b/arai60/kth_largest_element_in_a_stream/phase3.py @@ -12,4 +12,4 @@ def add(self, val: int) -> int: elif val >= self._min_heap[0]: heappushpop(self._min_heap, val) - return self._min_heap[0] \ No newline at end of file + return self._min_heap[0]