From 1739d7f8dcd32a0131737bf45fd07d579d5e4a79 Mon Sep 17 00:00:00 2001 From: brood0783 <213394875+brood0783@users.noreply.github.com> Date: Mon, 18 Aug 2025 10:09:06 +0900 Subject: [PATCH 1/3] Create 142. Linked List Cycle II.md --- .../142. Linked List Cycle II.md | 107 +++++++++--------- 1 file changed, 56 insertions(+), 51 deletions(-) diff --git a/142. Linked List Cycle II/142. Linked List Cycle II.md b/142. Linked List Cycle II/142. Linked List Cycle II.md index 7a87654..1d0844a 100644 --- a/142. Linked List Cycle II/142. Linked List Cycle II.md +++ b/142. Linked List Cycle II/142. Linked List Cycle II.md @@ -64,7 +64,7 @@ class Solution: ``` ```py -# 別解: fastとslowを用いる模範解答 +# 別解: fastとslowを用いる解法 class Solution: def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: if head is None: @@ -84,14 +84,14 @@ class Solution: slow = slow.next fast = fast.next return slow - ``` -[fastとslowを用いる模範解答](https://discord.com/channels/1084280443945353267/1195700948786491403/1196010117120925777) +``` +https://discord.com/channels/1084280443945353267/1195700948786491403/1196010117120925777 一番綺麗だと思う。この解答では、fast自体がNoneになるとnextに走査を送れない。面白い。修正する。 ```py -# fastとslowを用いる模範解答を綺麗にしたもの +# fastとslowを用いる解法を綺麗にしたもの class Solution: def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: if head is None: @@ -143,7 +143,7 @@ class Solution: ``` ```py -# Step2と全く同じ。4分程度で3連続AC。fastとslowを用いる模範解答を綺麗にしたもの +# Step2と全く同じ。4分程度で3連続AC。fastとslowを用いる解法を綺麗にしたもの class Solution: def detectCycle(self, head: Optional[ListNode]) -> Optional[ListNode]: if head is None: @@ -171,73 +171,78 @@ class Solution: ## 空間計算量の見積もり - setを使う解法 - 平均空間計算量: O(N) - ListNodeとsetがそれぞれどの程度要素数に比例してメモリを使うかを手元でみる。 - Nodeは1つにつき、どのくらいのサイズのメモリ占有を行っているか見る。 - + Node1つにつき、どのくらいのサイズのメモリ占有を行っているか見る。 + + sys.getsizeof(ListNode(1)): 48 bytes sys.getsizeof(ListNode(1).__dict__): 104 bytes sys.getsizeof(ListNode(1).val): 28 bytes sys.getsizeof(ListNode(1).next): 16 bytes - dictってこんな大きいのか。141.LinkedListCycle では、Nodeのインスタンス自体とvalのメモリ占有量を足して76 bytesとしていた(https://github.com/brood0783/arai60/pull/2/files#r2187906575 )が、インスタンスとdictの占有量を足して1ノード152 bytes程とするのが良いと思う。(Nodeの数)・152 bytesで見積もれそう。 - setはハッシュテーブルの埋まり具合に応じて、リサイズが起きる。the internal load factor(内部負荷率、ハッシュテーブルが埋まっている率)が3/5を超えるとリサイズが起きるようになっているらしい(https://stackoverflow.com/questions/75291343/what-is-the-internal-load-factor-of-a-sets-in-python )。 + sys.getsizeof(ListNode(1)): 48 bytes + sys.getsizeof(ListNode(1).__dict__): 104 bytes + sys.getsizeof(ListNode(1).val): 28 bytes + sys.getsizeof(ListNode(1).next): 16 bytes - === setリサイズ境界 === - 境界 1: 要素数 5 で 216 → 728 bytes (+512 bytes) - 境界 2: 要素数 19 で 728 → 2264 bytes (+1536 bytes) - 境界 3: 要素数 77 で 2264 → 8408 bytes (+6144 bytes) + dictってこんな大きいのか。141.LinkedListCycle では、Nodeのインスタンス自体とvalのメモリ占有量を足して76 bytesとしていた(https://github.com/brood0783/arai60/pull/2/files#r2187906575) が、インスタンスとdictの占有量を足して1ノード152 bytes程とするのが良いと思う。(Nodeの数)・152 bytesで見積もれそう。 - 要素数 2^6=64 について、 64・3/5=38 近辺でリサイズが起きていないのが不思議だが、(ListNodeの要素数)・107+216 bytes ほどで見積もれそう。 + setはハッシュテーブルの埋まり具合に応じて、リサイズが起きる。the internal load factor(内部負荷率、ハッシュテーブルが埋まっている率)が3/5を超えるとリサイズが起きるようになっているらしい(https://stackoverflow.com/questions/75291343/what-is-the-internal-load-factor-of-a-sets-in-python) + ``` + === setリサイズ境界 === + 境界 1: 要素数 5 で 216 → 728 bytes (+512 bytes) + 境界 2: 要素数 19 で 728 → 2264 bytes (+1536 bytes) + 境界 3: 要素数 77 で 2264 → 8408 bytes (+6144 bytes) + ``` - 最終的にはListNodeとsetで見積もった各値にバッファを設けて合計すれば、メモリ占有量は抑えられそう。 + 要素数2^6=64について、 64・3/5=38 近辺でリサイズが起きていないのが不思議だが、(ListNodeの要素数)・107+216 bytes ほどで見積もれそう。 + ListNodeとsetで見積もった各値にバッファを設けて合計すれば、メモリ占有量は抑えられそう。 - フロイドの循環検出法の場合 - 平均空間計算量: O(1) - - Nodeの数から見積もった値(Nodeの数・152 bytes)にバッファを設ければ、2つのポインター分のメモリも用意できそう。 + - Nodeの数から見積もった値(Nodeの数・152 bytes)にバッファを設ければ、2つのポインター分のメモリも用意できそう。 ## 時間計算量の見積もり - setを使う解法 - 平均時間計算量: O(N) - バッファを設けて1ノードにつき60nsで抑えられそう。setを使っているので、ノードが多いと探索が速い。 - - ``` - サイクル位置別の実行時間分析: - 100ノード: - 位置 0: 中央値 6167 ns - 位置 25: 中央値 5667 ns - 位置 50: 中央値 5583 ns - 位置 75: 中央値 5750 ns - 位置 99: 中央値 5709 ns - 1000ノード: - 位置 0: 中央値 53208 ns - 位置250: 中央値 50542 ns - 位置500: 中央値 50417 ns - 位置750: 中央値 50958 ns - 位置999: 中央値 54875 ns - ``` - + + ``` + サイクル位置別の実行時間分析: + 100ノード: + 位置 0: 中央値 6167 ns + 位置 25: 中央値 5667 ns + 位置 50: 中央値 5583 ns + 位置 75: 中央値 5750 ns + 位置 99: 中央値 5709 ns + 1000ノード: + 位置 0: 中央値 53208 ns + 位置250: 中央値 50542 ns + 位置500: 中央値 50417 ns + 位置750: 中央値 50958 ns + 位置999: 中央値 54875 ns + ``` + - フロイドの循環検出法 - 平均時間計算量: O(N) - - バッファを設けて1ノードにつき400nsで抑えられそう。サイクル位置が後ろになるほど、fastがたくさん動かなければいけないので時間かかる。 + - バッファを設けて1ノードにつき400nsで抑えられそう。fastがたくさん動かなければいけないので、サイクル位置が後ろになる程時間かかる。 - ``` - サイクル位置別の実行時間分析: - 100ノード: - 位置 0: 中央値 23042 ns - 位置 25: 中央値 21750 ns - 位置 50: 中央値 24709 ns - 位置 75: 中央値 34166 ns - 位置 99: 中央値 35875 ns - 1000ノード: - 位置 0: 中央値192667 ns - 位置250: 中央値199375 ns - 位置500: 中央値178750 ns - 位置750: 中央値262500 ns - 位置999: 中央値356083 ns - ``` + ``` + サイクル位置別の実行時間分析: + 100ノード: + 位置 0: 中央値 23042 ns + 位置 25: 中央値 21750 ns + 位置 50: 中央値 24709 ns + 位置 75: 中央値 34166 ns + 位置 99: 中央値 35875 ns + 1000ノード: + 位置 0: 中央値192667 ns + 位置250: 中央値199375 ns + 位置500: 中央値178750 ns + 位置750: 中央値262500 ns + 位置999: 中央値356083 ns + ``` From d69358c4c8dfd6cc48ab1d2b1355a912737c3d89 Mon Sep 17 00:00:00 2001 From: brood0783 <213394875+brood0783@users.noreply.github.com> Date: Mon, 18 Aug 2025 11:31:45 +0900 Subject: [PATCH 2/3] Clean up: Remove duplicate ListNode size logs, and retain the concise space complexity estimation. --- 142. Linked List Cycle II/142. Linked List Cycle II.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/142. Linked List Cycle II/142. Linked List Cycle II.md b/142. Linked List Cycle II/142. Linked List Cycle II.md index 1d0844a..a71d332 100644 --- a/142. Linked List Cycle II/142. Linked List Cycle II.md +++ b/142. Linked List Cycle II/142. Linked List Cycle II.md @@ -175,13 +175,6 @@ class Solution: Node1つにつき、どのくらいのサイズのメモリ占有を行っているか見る。 - - sys.getsizeof(ListNode(1)): 48 bytes - sys.getsizeof(ListNode(1).__dict__): 104 bytes - sys.getsizeof(ListNode(1).val): 28 bytes - sys.getsizeof(ListNode(1).next): 16 bytes - - sys.getsizeof(ListNode(1)): 48 bytes sys.getsizeof(ListNode(1).__dict__): 104 bytes sys.getsizeof(ListNode(1).val): 28 bytes From 258d9c321382d2694f1baeac07591901131cbd3a Mon Sep 17 00:00:00 2001 From: brood0783 <213394875+brood0783@users.noreply.github.com> Date: Mon, 18 Aug 2025 11:47:27 +0900 Subject: [PATCH 3/3] Fixed indentation and removed extra code fences --- .../142. Linked List Cycle II.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/142. Linked List Cycle II/142. Linked List Cycle II.md b/142. Linked List Cycle II/142. Linked List Cycle II.md index a71d332..e52678c 100644 --- a/142. Linked List Cycle II/142. Linked List Cycle II.md +++ b/142. Linked List Cycle II/142. Linked List Cycle II.md @@ -171,29 +171,29 @@ class Solution: ## 空間計算量の見積もり - setを使う解法 - 平均空間計算量: O(N) - ListNodeとsetがそれぞれどの程度要素数に比例してメモリを使うかを手元でみる。 - - Node1つにつき、どのくらいのサイズのメモリ占有を行っているか見る。 +ListNodeとsetがそれぞれどの程度要素数に比例してメモリを使うかを手元でみる。 + +Node1つにつき、どのくらいのサイズのメモリ占有を行っているか見る。 sys.getsizeof(ListNode(1)): 48 bytes sys.getsizeof(ListNode(1).__dict__): 104 bytes sys.getsizeof(ListNode(1).val): 28 bytes sys.getsizeof(ListNode(1).next): 16 bytes - dictってこんな大きいのか。141.LinkedListCycle では、Nodeのインスタンス自体とvalのメモリ占有量を足して76 bytesとしていた(https://github.com/brood0783/arai60/pull/2/files#r2187906575) が、インスタンスとdictの占有量を足して1ノード152 bytes程とするのが良いと思う。(Nodeの数)・152 bytesで見積もれそう。 +dictってこんな大きいのか。141.LinkedListCycle では、Nodeのインスタンス自体とvalのメモリ占有量を足して76 bytesとしていた(https://github.com/brood0783/arai60/pull/2/files#r2187906575) が、インスタンスとdictの占有量を足して1ノード152 bytes程とするのが良いと思う。(Nodeの数)・152 bytesで見積もれそう。 + +setはハッシュテーブルの埋まり具合に応じて、リサイズが起きる。the internal load factor(内部負荷率、ハッシュテーブルが埋まっている率)が3/5を超えるとリサイズが起きるようになっているらしい(https://stackoverflow.com/questions/75291343/what-is-the-internal-load-factor-of-a-sets-in-python) - setはハッシュテーブルの埋まり具合に応じて、リサイズが起きる。the internal load factor(内部負荷率、ハッシュテーブルが埋まっている率)が3/5を超えるとリサイズが起きるようになっているらしい(https://stackoverflow.com/questions/75291343/what-is-the-internal-load-factor-of-a-sets-in-python) - ``` === setリサイズ境界 === 境界 1: 要素数 5 で 216 → 728 bytes (+512 bytes) 境界 2: 要素数 19 で 728 → 2264 bytes (+1536 bytes) 境界 3: 要素数 77 で 2264 → 8408 bytes (+6144 bytes) - ``` - 要素数2^6=64について、 64・3/5=38 近辺でリサイズが起きていないのが不思議だが、(ListNodeの要素数)・107+216 bytes ほどで見積もれそう。 - ListNodeとsetで見積もった各値にバッファを設けて合計すれば、メモリ占有量は抑えられそう。 +要素数2^6=64について、 64・3/5=38 近辺でリサイズが起きていないのが不思議だが、(ListNodeの要素数)・107+216 bytes ほどで見積もれそう。 + +ListNodeとsetで見積もった各値にバッファを設けて合計すれば、メモリ占有量は抑えられそう。 - フロイドの循環検出法の場合 - 平均空間計算量: O(1)