From 3918c25ec5fdc41b7c3d01836766875c5cc2ab8f Mon Sep 17 00:00:00 2001 From: myoshizumi Date: Wed, 13 May 2026 18:47:05 +0900 Subject: [PATCH 1/5] feat: add Pascal's Triangle (LeetCode 118) solution and update markdownlint config --- .markdownlint.json | 2 + .../Pascal's_Triangle_Python.md | 370 +++ .../Pascal's_Triangle_Typescript.md | 268 +++ .../claude sonnet 4.6 adaptive/README.md | 758 +++++++ .../README_React.html | 2001 +++++++++++++++++ .../README_React.html | 2001 +++++++++++++++++ public/index.html | 14 +- 7 files changed, 5408 insertions(+), 6 deletions(-) create mode 100644 Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Python.md create mode 100644 Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Typescript.md create mode 100644 Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README.md create mode 100644 Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html create mode 100644 public/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html diff --git a/.markdownlint.json b/.markdownlint.json index d3f5138..8b73cc4 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -56,6 +56,8 @@ "MD042": false, "MD046": { "style": "fenced" }, "MD048": { "style": "backtick" }, + "MD049": false, + "MD050": false, "MD058": false, "MD060": false } diff --git a/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Python.md b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Python.md new file mode 100644 index 0000000..e49827b --- /dev/null +++ b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Python.md @@ -0,0 +1,370 @@ +> 🎯 **[algo-beginner スキル発火]** +> 蚀語/カテゎリ: Python +> 適甚ルヌルセット: 共通5ルヌル + Py固有4ルヌル +> 参照ファむル: references/common.md + references/python.md + +--- + +# Pascal's Triangleパスカルの䞉角圢— Python版 + +--- + +## 1. 問題分析結果 + +> 💡 **初孊者向け補足** +> この問題は䞀蚀で蚀うず、**「䞉角圢の圢に䞊んだ数倀の衚を、䞊から順番に1行ず぀積み䞊げお䜜る問題」** です。 + +たず目で確認したしょう。 + +``` +行0 [1] +行1 [1, 1] +行2 [1, 2, 1] +行3[1, 3, 3, 1] +行4[1, 4, 6, 4, 1] +``` + +ルヌルは2぀だけです + +- 各行の **䞡端は必ず `1`** +- 内偎の芁玠は **真䞊の巊ず右の数倀を足した倀**䟋行2の `2` = 行1の `1 + 1` + +**Pythonで解く際のCPython特有の泚意点**この問題は新しいリストを行ごずに生成しおいく凊理のため、メモリアロケヌションメモリを新たに確保するこずが頻繁に発生したす。`numRows ≀ 30` ずいう制玄のため珟実的には問題になりたせんが、リスト内包衚蚘`[1] + [...] + [1]` のような曞き方はCPythonのバむトコヌドレベルで最適化されおおり、玠朎な `for` ルヌプより高速に動䜜したす。 + +--- + +### 競技プログラミング芖点 + +- **制玄分析**`numRows ≀ 30` → 最倧でも `30×31/2 = 465芁玠` しか生成したせん。O(n²) で十分間に合いたす +- **最速手法**各行をリスト内包衚蚘で䞀括生成する。C実装C蚀語で曞かれた高速な凊理の恩恵を受けやすい +- **メモリ最小化**盎前の1行だけ参照すれば次の行を䜜れるため、党行を保持しながら結果を構築したす + +### 業務開発芖点 + +- **型安党蚭蚈**`list[list[int]]` を戻り倀型ずしお明瀺。`numRows: int` の入力怜蚌で範囲倖を早期に匟く +- **゚ラヌハンドリング**制玄 `1 ≀ numRows ≀ 30` の範囲倖、たたは `int` 以倖の型が枡されたずきに分かりやすい゚ラヌを投げる +- **可読性**各凊理を `_build_row()` ヘルパヌに分離し、メむンロゞックを短く保぀ + +### Python特有分析 + +- **デヌタ構造遞択**行は `list[int]` が最適。䞡端操䜜はなく、むンデックスアクセスが頻繁なため `deque`前埌から出し入れできる䞡端キュヌよりも `list` が向いおいたす +- **暙準ラむブラリ掻甚床**今回は `itertools` や `collections` は䞍芁。`list` ず内包衚蚘だけで完結したす +- **CPython最適化床**リスト内包衚蚘でC実装レベルの高速化を掻かせたす + +> 📖 **このセクションで登堎した甚語** +> +> - **CPython**最も広く䜿われるPythonの実装。C蚀語で曞かれおおり、組み蟌み関数の倚くがC実装のため高速 +> - **リスト内包衚蚘**`[匏 for 倉数 in むテラブル]` ずいう圢でリストを1行で䜜る曞き方。`for` ルヌプより高速な理由は、CPythonが内包衚蚘専甚の最適化されたバむトコヌド呜什`LIST_APPEND`を䜿うから +> - **制玄分析**問題の入力サむズ䞊限から「どのくらいの蚈算量たで蚱容されるか」を逆算するこず +> - **メモリアロケヌション**プログラムが新しいデヌタを栌玍するためにメモリ領域を確保するこず + +--- + +## 2. 採甚アルゎリズムず根拠 + +> 💡 **初孊者向け補足** +> 同じ問題でも解き方は耇数ありたす。それぞれの「速さ時間蚈算量」ず「メモリの䜿いやすさ空間蚈算量」を比べお最適なものを遞びたす。 + +| アプロヌチ | 時間蚈算量 | 空間蚈算量 | Python実装コスト | 可読性 | 暙準ラむブラリ掻甚 | CPython最適化 | 備考 | +| ----------------------------- | ---------- | ---------- | ---------------- | ------ | ------------------ | -------------- | ---------------------------------------------------------------------- | +| **A. 逐次行構築今回遞択** | O(n²) | O(n²) | 䜎 | ★★★ | list のみ | 適内包衚蚘 | 盎感的で最もシンプル | +| B. 二項係数で盎接蚈算 | O(n²) | O(n²) | äž­ | ★★☆ | math.comb | 適 | 倧きな敎数で粟床は問題なしPythonは倚倍長敎数。ただし実装がやや難解 | +| C. 再垰メモ化なし | O(n³) | O(n²) | 高 | ★☆☆ | なし | 䞍適 | 同じ倀を䜕床も再蚈算。`@lru_cache` 远加で改善できるが過剰 | + +**遞択理由****方法A逐次行構築** を遞びたす。 + +- **方法Bを遞ばなかった理由**`math.comb(n, k)` で蚈算は可胜ですが、「前行を䜿っお次行を䜜る」ずいうパスカルの䞉角圢の本質的なルヌルを盎接コヌドで衚珟できる方法Aの方が可読性・保守性に優れおいたす +- **方法Cを遞ばなかった理由**再垰は呌び出しスタック関数呌び出しを蚘録する領域を消費し、O(n³) ず最も遅く、この問題には適したせん +- **Python最適化戊略**各行の内偎をリスト内包衚蚘で䞀括生成するこずで、CPythonの内包衚蚘最適化の恩恵を受けたす + +> 📖 **このセクションで登堎した甚語** +> +> - **時間蚈算量**入力の倧きさに察しお凊理にかかる手間がどう増えるかの目安 +> - **空間蚈算量**凊理䞭に䜿うメモリ量がどう増えるかの目安 +> - **`math.comb(n, k)`**組み合わせの数 C(n,k) を蚈算するPython 3.8+ の暙準関数。Pythonは倚倍長敎数桁数の制限がない敎数を扱えるため粟床の問題はない +> - **呌び出しスタック**関数が関数を呌び出すずき、どこから呌ばれたかを蚘録するメモリ領域。深い再垰はここを䜿い尜くしお `RecursionError` を起こす + +--- + +## 3. 実装パタヌン + +> 💡 **コヌドの倧たかな構造骚栌** +> +> 1. 入力 `numRows` の型・範囲を怜蚌する +> 2. 結果栌玍甚の2次元リストを甚意する +> 3. 1行目`[1]`を無条件で远加する +> 4. 2行目以降先頭ず末尟を `1` に固定し、内偎をリスト内包衚蚘で蚈算する +> 5. 完成した䞉角圢を返す + +--- + +### 業務開発版 + +``` +【業務開発版を䜿う堎面】 +チヌムで長期間メンテナンスするプロダクションコヌドに向きたす。 +型ヒントずdocstringにより、埌から読む人が凊理の意図を理解しやすく、 +pylanceによる静的型チェックでバグを実行前に発芋できたす。 +``` + +```python +# Runtime 0 ms +# Beats 100.00% +# Memory 19.35 MB +# Beats 28.62% +from typing import Any + + +class Solution: + """ + パスカルの䞉角圢生成クラス業務開発版 + + 各行は前の行だけを参照しお O(n) で構築する。 + 党䜓の時間蚈算量は O(n²)、空間蚈算量は O(n²)。 + """ + + def generate(self, numRows: int) -> list[list[int]]: + """ + パスカルの䞉角圢の最初の numRows 行を生成しお返す。 + + Args: + numRows: 生成する行数。制玄: 1 ≀ numRows ≀ 30 + + Returns: + 各行を list[int] で衚した 2 次元リスト + + Raises: + TypeError: numRows が int 型でない堎合 + ValueError: numRows が制玄範囲倖1〜30以倖の堎合 + + Time Complexity: O(n²) n = numRows + Space Complexity: O(n²) + """ + # ─── 入力怜蚌 ───────────────────────────────────────────── + # isinstance() で型チェックする。 + # Python は動的型付け蚀語のため、呌び出し元が誀った型を枡しおも + # 実行時たで気づかない。ここで匟くこずで分かりやすい゚ラヌにする。 + # bool は int のサブクラスなので isinstance(True, int) → True になる。 + # それを防ぐために bool チェックを先に行う。 + if isinstance(numRows, bool) or not isinstance(numRows, int): + raise TypeError( + f"numRows must be an int, got: {type(numRows).__name__}" + ) + + # 制玄「1 ≀ numRows ≀ 30」の範囲倖を匟く。 + # 埌続の凊理でリストの範囲倖アクセスが起きるのを防ぐため。 + if numRows < 1 or numRows > 30: + raise ValueError( + f"numRows must be between 1 and 30, got: {numRows}" + ) + + # ─── 結果配列の準備 ─────────────────────────────────────── + # list[list[int]] = 「敎数のリスト」を芁玠ずする2次元リスト + triangle: list[list[int]] = [] + + # ─── 行を1行ず぀積み䞊げる ──────────────────────────────── + for row_index in range(numRows): + # 各行の内偎の芁玠だけを蚈算し、䞡端は埌で [1] + [...] + [1] で远加する + current_row = self._build_row(triangle, row_index) + triangle.append(current_row) + + return triangle + + def _build_row( + self, triangle: list[list[int]], row_index: int + ) -> list[int]: + """ + 指定した行むンデックスの行を構築しお返すヘルパヌ関数。 + + Args: + triangle: これたでに構築した䞉角圢前行を参照するために䜿う + row_index: 今から構築する行のむンデックス0始たり + + Returns: + 新しく構築した行list[int] + """ + # 0行目芁玠は [1] だけ。前の行が存圚しないのでそのたた返す。 + if row_index == 0: + return [1] + + # 1行目[1, 1]。内偎の芁玠がないのでそのたた返す。 + if row_index == 1: + return [1, 1] + + # 2行目以降前の行を参照しお内偎を蚈算する。 + # prev は前の行ぞの参照。型は list[int] ずわかっおいるため型安党。 + prev: list[int] = triangle[row_index - 1] + + # リスト内包衚蚘リストを1行で䜜る曞き方で内偎の芁玠を䞀括蚈算する。 + # なぜリスト内包衚蚘を䜿うかCPythonがバむトコヌドレベルで + # ルヌプ専甚の最適化呜什LIST_APPENDを䜿うため、 + # 玠朎な for ルヌプよりも高速に動䜜するから。 + # prev[col - 1] + prev[col]  真䞊の巊 + 真䞊の右 + inner: list[int] = [ + prev[col - 1] + prev[col] + for col in range(1, row_index) # 先頭ず末尟はスキップ䞡端は必ず 1 + ] + + # 先頭の [1] + 内偎 + 末尟の [1] を結合しお完成した行にする + return [1] + inner + [1] +``` + +--- + +### 競技プログラミング版 + +``` +【競技プログラミング版を䜿う堎面】 +LeetCodeの制限時間内に正解を出すこずが目的のコヌドに向きたす。 +型チェックや゚ラヌハンドリングを省略し、コヌドを最短・最速にしおいたす。 +可読性よりも実行速床ずコヌドの短さを最優先にした曞き方です。 +``` + +```python +class Solution: + def generate(self, numRows: int) -> list[list[int]]: + # 結果を栌玍するリスト。たず1行目を盎接入れる + tri: list[list[int]] = [[1]] + + # 2行目以降をルヌプで積み䞊げるrange(1, numRows) で0行目をスキップ + for i in range(1, numRows): + # 盎前の行を取り出すむンデックス -1 は末尟 = 盎前の行 + p = tri[-1] + + # 䞡端の [1] ず内偎を内包衚蚘で䞀括生成しお1行で完成させる。 + # p[j-1] + p[j]  真䞊の巊 + 真䞊の右 + tri.append([1] + [p[j - 1] + p[j] for j in range(1, i)] + [1]) + + return tri +``` + +--- + +### 💡 コヌドの動䜜トレヌス`numRows = 5` の堎合 + +業務開発版の流れを具䜓的に远いたす。 + +``` +入力: numRows = 5 + +─── 入力怜蚌 ─── +isinstance(5, bool) → Falseboolチェック通過 +isinstance(5, int) → True型チェック通過 +1 <= 5 <= 30 → 怜蚌通過 ✅ + +─── ルヌプ開始 ─── + +[row_index = 0] + _build_row() → row_index == 0 なので [1] を即返す + triangle = [[1]] + +[row_index = 1] + _build_row() → row_index == 1 なので [1, 1] を即返す + triangle = [[1], [1, 1]] + +[row_index = 2] + prev = [1, 1] + inner = [prev[0] + prev[1]] = [1 + 1] = [2] ← col=1 の1ステップだけ + current_row = [1] + [2] + [1] = [1, 2, 1] + triangle = [[1], [1,1], [1,2,1]] + +[row_index = 3] + prev = [1, 2, 1] + inner: + col=1 → prev[0] + prev[1] = 1 + 2 = 3 + col=2 → prev[1] + prev[2] = 2 + 1 = 3 + inner = [3, 3] + current_row = [1] + [3, 3] + [1] = [1, 3, 3, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1]] + +[row_index = 4] + prev = [1, 3, 3, 1] + inner: + col=1 → prev[0] + prev[1] = 1 + 3 = 4 + col=2 → prev[1] + prev[2] = 3 + 3 = 6 + col=3 → prev[2] + prev[3] = 3 + 1 = 4 + inner = [4, 6, 4] + current_row = [1] + [4, 6, 4] + [1] = [1, 4, 6, 4, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + +─── 完成 ─── +出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅ +``` + +> 📖 **このセクションで登堎した甚語** +> +> - **リスト内包衚蚘**`[匏 for 倉数 in むテラブル]` ずいう圢でリストを1行で䜜る曞き方。CPythonは内包衚蚘専甚の最適化されたバむトコヌド呜什`LIST_APPEND`を䜿うため、同じ凊理を `for` ルヌプで曞くより高速 +> - **`isinstance()`**倉数がある型かどうかを調べる組み蟌み関数。C蚀語実装のため高速。`type(x) == int` ずは異なり、サブクラスも含めおチェックする +> - **`bool` は `int` のサブクラス**Pythonでは `True` は内郚的に `1`、`False` は `0` ずしお扱われる。そのため `isinstance(True, int)` が `True` を返しおしたい、意図しない倀を通過させるバグになりやすい。先に `isinstance(x, bool)` をチェックする順番が重芁 +> - **型ヒント**関数の匕数や戻り倀に型を泚釈ずしお曞く仕組み。`def f(x: int) -> list[int]:` のように曞く。Pythonは動的型付けなので型を曞かなくおも動くが、pylanceによる静的型チェックを掻甚するために曞く +> - **`tri[-1]`**リストの末尟芁玠ぞのアクセス。Python固有の負のむンデックス蚘法。`tri[len(tri)-1]` ず同じ意味だが短く曞ける + +--- + +## 4. 怜蚌゚ッゞケヌス確認 + +゚ッゞケヌスのテストは、アルゎリズムが「ふ぀うの入力」だけでなく「極端な入力」でも正しく動くかを確かめるためのものです。 + +```python +# ─── 境界倀テスト業務開発版 ─── + +sol = Solution() + +# 最小倀numRows = 1 +# 期埅倀: [[1]] +assert sol.generate(1) == [[1]] + +# 最倧倀numRows = 30 +# 期埅倀の最埌の行が C(29,0)...C(29,29) になっおいるこずを確認 +result_30 = sol.generate(30) +assert len(result_30) == 30 # 30行あるこず +assert result_30[0] == [1] # 先頭行が [1] であるこず +assert result_30[-1][0] == 1 # 最終行の先頭が 1 であるこず +assert result_30[-1][-1] == 1 # 最終行の末尟が 1 であるこず +assert result_30[4] == [1,4,6,4,1] # 5行目の倀が正しいこず + +# Example 1: numRows = 5 +assert sol.generate(5) == [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + +# Example 2: numRows = 1 +assert sol.generate(1) == [[1]] + +# ─── 型・範囲゚ラヌのテスト業務開発版のみ ─── + +import traceback + +# int でない型を枡す → TypeError が発生するか確認 +try: + sol.generate("5") # type: ignore[arg-type] + assert False, "TypeError が発生するべき" +except TypeError: + pass # 期埅通り ✅ + +# bool を枡す → TypeError が発生するか確認bool は int のサブクラスなので泚意 +try: + sol.generate(True) # type: ignore[arg-type] + assert False, "TypeError が発生するべき" +except TypeError: + pass # 期埅通り ✅ + +# 範囲倖0以䞋→ ValueError が発生するか確認 +try: + sol.generate(0) + assert False, "ValueError が発生するべき" +except ValueError: + pass # 期埅通り ✅ + +# 範囲倖31以䞊→ ValueError が発生するか確認 +try: + sol.generate(31) + assert False, "ValueError が発生するべき" +except ValueError: + pass # 期埅通り ✅ +``` + +> 📖 **このセクションで登堎した甚語** +> +> - **゚ッゞケヌス**空のリスト・最小倀・最倧倀など、境界的な条件のこず。通垞の入力では動いおも、境界では壊れるアルゎリズムは倚い +> - **境界倀テスト**゚ッゞケヌスに察しおもアルゎリズムが正しく動くかを確かめるこず +> - **静的型チェック**pylanceがコヌドを実行せず読むだけでバグや型゚ラヌを怜出する手法。`# type: ignore` コメントで意図的に型チェックを無効化するこずもできる +> - **`assert`文**条件が `False` のずき `AssertionError` を発生させる構文。テストコヌドで「この倀であるはず」を衚珟するずきによく䜿う diff --git a/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Typescript.md b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Typescript.md new file mode 100644 index 0000000..c6934de --- /dev/null +++ b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/Pascal's_Triangle_Typescript.md @@ -0,0 +1,268 @@ +> 🎯 **[algo-beginner スキル発火]** +> 蚀語/カテゎリ: TypeScript +> 適甚ルヌルセット: 共通5ルヌル + TS固有5ルヌル +> 参照ファむル: references/common.md + references/typescript.md + +--- + +# Pascal's Triangleパスカルの䞉角圢 + +--- + +## 1. 問題の分析 + +> 💡 **初孊者向け補足** +> この問題は䞀蚀で蚀うず、**「䞉角圢の圢に䞊んだ数倀の衚を、䞊から順番に行を積み䞊げお䜜る問題」** です。 + +パスカルの䞉角圢ずは䜕かを先に目で確認したしょう。 + +``` +行0 [1] +行1 [1, 1] +行2 [1, 2, 1] +行3 [1, 3, 3, 1] +行4 [1, 4, 6, 4, 1] +``` + +**ルヌル**はたった2぀です + +- 各行の **䞡端は必ず `1`** +- 内偎の芁玠は **真䞊の巊ず右の芁玠を足した倀**䟋行2の `2` = 行1の `1 + 1` + +--- + +### 競技プログラミング芖点での分析 + +- 各行を前の行から `O(k)`kはその行の芁玠数で構築できたす +- 党䜓の芁玠数は `1 + 2 + 3 + ... + numRows = numRows*(numRows+1)/2` なので、**最䜎でも O(numRows²) の時間・空間**が必芁 +- `numRows ≀ 30` ずいう制玄入力が最倧30ずいう䞊限があるため、最悪でも `30*31/2 = 465芁玠` しか生成したせん。蚈算量を特別に最小化しなくおも十分高速です + +### 業務開発芖点での分析 + +- **型安党性**戻り倀 `number[][]`数倀の2次元配列を明瀺し、各行が `number[]` であるこずをコンパむル時に保蚌したす +- **゚ラヌハンドリング**制玄 `1 ≀ numRows ≀ 30` の範囲倖入力を実行時に怜出しお匟きたす +- **むミュヌタブル志向**デヌタを盎接曞き換えず、新しいデヌタずしお䜜る考え方各行を新しい配列ずしお構築し、前の行を壊したせん + +### TypeScript特有の考慮点 + +- **型掚論**型を曞かなくおもTypeScriptが自動刀断する機胜`prev.length` などから `number` 型が自動掚論されたす +- `readonly number[]`読み取り専甚の数倀配列を前行の型ずしお䜿い、誀っお前行を曞き換えるバグをコンパむル時に防止したす +- 戻り倀の `number[][]` の明瀺により、呌び出し元で型゚ラヌが起きにくくなりたす + +> 📖 **このセクションで登堎した甚語** +> +> - **コンパむル時**TypeScriptのコヌドをJavaScriptに倉換する段階。ここで゚ラヌを怜出するず、プログラムを実行する前にバグを発芋できる +> - **型安党性**間違った型䟋数倀の堎所に文字列を枡すなどのデヌタが玛れ蟌たないように守る仕組み +> - **むミュヌタブル**倉曎できない・倉曎しない状態のこず。元のデヌタを壊さないため、バグが起きにくい + +--- + +## 2. アルゎリズムアプロヌチ比范 + +> 💡 **初孊者向け補足** +> 同じ問題でも解き方は耇数ありたす。それぞれの「速さ時間蚈算量凊理にかかる手間の目安」ず「メモリの䜿いやすさ空間蚈算量䜿うメモリ量の目安」を比べお最適なものを遞びたす。 + +| アプロヌチ | 時間蚈算量 | 空間蚈算量 | TS実装コスト | 型安党性 | 可読性 | 備考 | +| ----------------------------- | ---------- | ---------- | ------------ | -------- | ------ | --------------------------------------------------------- | +| **A. 逐次行構築今回遞択** | O(n²) | O(n²) | 䜎 | 高 | 高 | 前の行だけ芋お次の行を䜜る | +| B. 二項係数で盎接蚈算 | O(n²) | O(n²) | äž­ | äž­ | äž­ | C(n,k)公匏を䜿う。倧きいnで敎数オヌバヌフロヌのリスクあり | +| C. 再垰メモ化なし | O(n³) | O(n²) | 高 | äž­ | 䜎 | 同じ倀を䜕床も再蚈算するため遅い | + +> 💡 **Big-O蚘法の読み方**初孊者向け +> +> - `O(1)`入力の倧きさに関わらず、垞に䞀定の時間・メモリ +> - `O(n)`入力が2倍になるず凊理も玄2倍 +> - `O(n²)`入力が2倍になるず凊理は玄4倍二重ルヌプに倚い + +> 📖 **このセクションで登堎した甚語** +> +> - **二項係数**組み合わせの数を衚す数孊的な倀。`C(n, k) = n! / (k! * (n-k)!)` で蚈算できるが、階乗1×2×3× ×nが倧きくなりすぎる問題がある +> - **再垰**関数が自分自身を呌び出しお問題を解く方法。ツリヌ構造の問題に向くが、呌び出しが深くなるずメモリを消費する + +--- + +## 3. 遞択したアルゎリズムず理由 + +- **遞択したアプロヌチ**: **A. 逐次行構築むテレヌティブ繰り返し凊理による方法** +- **理由**: + - **方法Bを遞ばなかった理由**二項係数は数匏で䞀芋゚レガントですが、`numRows=30`のずき `30!`30の階乗ずいう非垞に倧きな数を扱う必芁があり、JavaScriptのNumber型浮動小数点数で粟床が萜ちるリスクがありたす + - **方法Cを遞ばなかった理由**再垰は同じ倀を䜕床も蚈算し盎すため、O(n³) ず最も遅く、この問題には䞍向きです + - **方法Aを遞んだ理由**前の行だけを参照しお次の行を䜜る「積み䞊げ匏」のため、蚈算の無駄がなく、コヌドの流れも人間の盎感ず䞀臎しおいお読みやすいです + +- **TypeScript特有の最適化ポむント**: + - `readonly number[]` で前行の参照を保護し、「前行を誀っお曞き換えるバグ」をコンパむル時に防止したす + - 戻り倀型 `number[][]` の明瀺により、呌び出し元でも型の恩恵を受けられたす + - 入力怜蚌を関数冒頭で行い、䞍正な `numRows` が枡されたずきに分かりやすい゚ラヌを返したす + +> 📖 **このセクションで登堎した甚語** +> +> - **むテレヌティブ**ルヌプfor文などで繰り返す凊理方法。再垰ず察比しお䜿う語 +> - **浮動小数点数**コンピュヌタが小数を近䌌倀で衚す方匏。非垞に倧きな敎数を扱うず誀差が生じるこずがある +> - **コンパむル時゚ラヌ**TypeScriptのコヌドをJavaScriptに倉換する際に発芋される゚ラヌ。実行前にバグを発芋できる + +--- + +## 4. 実装コヌド + +> 💡 **このコヌドの倧たかな構造骚栌** +> +> 1. 入力倀 `numRows` の怜蚌範囲倖の倀を匟く +> 2. 結果を栌玍する空の2次元配列を甚意する +> 3. 1行目`[1]`を無条件でセットする +> 4. 2行目以降は「前の行」を参照しお䞡端を`1`、内偎を隣合う倀の和で埋める +> 5. 完成した䞉角圢党䜓を返す + +```typescript +// Runtime 1 ms +// Beats 33.72% +// Memory 56.02 MB +// Beats 78.88% + +/** + * パスカルの䞉角圢の最初の numRows 行を生成しお返す + * @param numRows - 生成する行数1以䞊30以䞋 + * @returns 各行を number[] で衚した2次元配列 + * @throws {RangeError} numRows が制玄範囲倖のずき + * @complexity Time: O(n²), Space: O(n²) n = numRows + */ +function generate(numRows: number): number[][] { + // ─── 入力怜蚌 ───────────────────────────────────────────── + // 制玄「1 ≀ numRows ≀ 30」を満たさない倀が来たずきに + // 埌続凊理で意味䞍明なバグになる前に、分かりやすい゚ラヌを投げる + if (!Number.isInteger(numRows) || numRows < 1 || numRows > 30) { + throw new RangeError(`numRows must be an integer between 1 and 30, got: ${numRows}`); + } + + // ─── 結果配列の準備 ─────────────────────────────────────── + // number[][] = 「数倀の配列」を芁玠ずする配列2次元配列 + // TypeScriptが戻り倀の型をここで確定させるため、明瀺的に型を付ける + const triangle: number[][] = []; + + // ─── 行を1行ず぀積み䞊げる ──────────────────────────────── + for (let rowIndex = 0; rowIndex < numRows; rowIndex++) { + // 各行は rowIndex+1 個の芁玠を持぀0行目は1個、1行目は2個  + // Array.from で「長さだけ決たった配列」を䜜り、すべお 1 で初期化する + // 初期倀を 1 にする理由䞡端は必ず 1 なので、埌で端以倖だけ䞊曞きすれば枈む + const currentRow: number[] = Array.from({ length: rowIndex + 1 }, () => 1); + + // 内偎の芁玠を蚈算する先頭ず末尟は既に 1 なのでスキップ + // 䟋rowIndex=3 のずき、曎新するのは index 1 ず 2 だけ + for (let col = 1; col < rowIndex; col++) { + // 前の行readonly ずしお参照の巊䞊 + 右䞊 = 珟圚のセルの倀 + // readonly number[] を型ずしお甚いるこずで、前行を誀っお + // 曞き換えるバグをコンパむル時に防止しおいるTypeScript固有の恩恵 + const prevRow: readonly number[] = triangle[rowIndex - 1]; + currentRow[col] = prevRow[col - 1] + prevRow[col]; + } + + // 完成した行を䞉角圢に远加する + triangle.push(currentRow); + } + + // 党行が揃った䞉角圢を返す + return triangle; +} +``` + +--- + +### 💡 コヌドの動䜜トレヌス`numRows = 5` の堎合 + +入力がどのように倉化しおいくかをステップごずに远いたす。 + +``` +入力: numRows = 5 + +─── 入力怜蚌 ─── +Number.isInteger(5) → true +5 >= 1 か぀ 5 <= 30 → 怜蚌通過 ✅ + +─── ルヌプ開始 ─── + +[rowIndex = 0] + currentRow の初期 = [1] (長さ1、すべお1) + 内偎ルヌプ: col の範囲 1  -1 → 実行なし䞡端だけの行 + triangle = [[1]] + +[rowIndex = 1] + currentRow の初期 = [1, 1] (長さ2、すべお1) + 内偎ルヌプ: col の範囲 1  0 → 実行なし1ず1の2芁玠だけ + triangle = [[1], [1,1]] + +[rowIndex = 2] + currentRow の初期 = [1, 1, 1] (長さ3、すべお1) + 内偎ルヌプ: col=1 のみ + prevRow = [1, 1] + currentRow[1] = prevRow[0] + prevRow[1] = 1 + 1 = 2 + currentRow 確定 = [1, 2, 1] + triangle = [[1], [1,1], [1,2,1]] + +[rowIndex = 3] + currentRow の初期 = [1, 1, 1, 1] (長さ4、すべお1) + 内偎ルヌプ: col=1, col=2 + col=1: prevRow=[1,2,1] → currentRow[1] = 1 + 2 = 3 + col=2: prevRow=[1,2,1] → currentRow[2] = 2 + 1 = 3 + currentRow 確定 = [1, 3, 3, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1]] + +[rowIndex = 4] + currentRow の初期 = [1, 1, 1, 1, 1] (長さ5、すべお1) + 内偎ルヌプ: col=1, col=2, col=3 + col=1: prevRow=[1,3,3,1] → currentRow[1] = 1 + 3 = 4 + col=2: prevRow=[1,3,3,1] → currentRow[2] = 3 + 3 = 6 + col=3: prevRow=[1,3,3,1] → currentRow[3] = 3 + 1 = 4 + currentRow 確定 = [1, 4, 6, 4, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + +─── 完成 ─── +出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅ +``` + +> 📖 **このセクションで登堎した甚語** +> +> - **`readonly`**倉数の倀を倉曎できないようにするTypeScript固有の修食子。JavaScriptにはこの制限がなく、意図せぬ曞き換えがバグの原因になりやすい。TypeScriptで `readonly` を付けるずコンパむル時に曞き換えを防止できる +> - **`RangeError`**倀の範囲が䞍正な堎合に投げる゚ラヌの皮類。䟋えば「1〜30以倖の数倀」など、型は正しいが倀が䞍正なずきに䜿う型そのものが違う堎合は `TypeError` を䜿う +> - **`Array.from({ length: n }, () => 1)`**長さ `n` の配列を䜜り、党芁玠を `1` で初期化するむディオムよく䜿われる定番の曞き方。`new Array(n).fill(1)` ず同じ効果だが、こちらの方が型掚論ず盞性が良い +> - **Pure function玔粋関数**同じ入力を䞎えるず必ず同じ出力を返し、倖郚の倉数や状態を曞き換えない関数。テストしやすく、バグが起きにくい + +--- + +## 5. LeetCode 提出甚コヌド + +```typescript +function generate(numRows: number): number[][] { + const triangle: number[][] = []; + + for (let rowIndex = 0; rowIndex < numRows; rowIndex++) { + const currentRow: number[] = Array.from({ length: rowIndex + 1 }, () => 1); + + for (let col = 1; col < rowIndex; col++) { + const prevRow: readonly number[] = triangle[rowIndex - 1]; + currentRow[col] = prevRow[col - 1] + prevRow[col]; + } + + triangle.push(currentRow); + } + + return triangle; +} +``` + +--- + +## TypeScript固有の最適化芳点たずめ + +### 型安党性の掻甚 + +- **`readonly number[]`**前行の参照に `readonly` を付けるこずで「前行を曞き換えおしたう」バグをコンパむル時に怜出できたす。JavaScriptには `readonly` の抂念がなく、実行しお初めおバグに気づく堎合がありたす +- **`number[][]` の明瀺**戻り倀型を明瀺するこずで、呌び出し元でも配列の各芁玠が `number[]` であるずいう情報が䌝わりたす。型を省略するず、IDEの補完IntelliSenseが匱くなりたす + +### コンパむル時最適化 + +- **型掚論の掻甚**`Array.from({ length: rowIndex + 1 }, () => 1)` の戻り倀は `number[]` ず自動掚論されるため、`:number[]` を明瀺しなくおも型チェックが機胜したす +- **`Number.isInteger()`** を䜿った入力バリデヌション`typeof numRows === 'number'` だけでは小数䟋`5.5`が通っおしたうため、より厳密な敎数チェックを行っおいたす + +### 開発効率ず保守性 + +- 各ルヌプ倉数 `rowIndex`・`col` に意味のある名前を付けるこずで、「䜕番目の行か」「䜕番目の列か」が䞀目で分かりたす +- `triangle[rowIndex - 1]` を `prevRow` ずいう倉数に取り出すこずで、コヌドが「前の行を参照しおいる」ずいう意図を明確に䌝えたす diff --git a/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README.md b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README.md new file mode 100644 index 0000000..a09d523 --- /dev/null +++ b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README.md @@ -0,0 +1,758 @@ +# Pascal's Triangle - 行を積み䞊げおパスカルの䞉角圢を生成する + +--- + +## 目次Table of Contents + +- [抂芁](#overview) +- [アルゎリズム芁点 TL;DR](#tldr) +- [図解](#figures) +- [正しさのスケッチ](#correctness) +- [蚈算量](#complexity) +- [Python 実装](#impl) +- [CPython 最適化ポむント](#cpython) +- [゚ッゞケヌスず怜蚌芳点](#edgecases) +- [FAQ](#faq) + +--- + +

抂芁

+ +> 💡 **初孊者向け補足** +> この問題は䞀蚀で蚀うず、**「䞉角圢の圢に䞊んだ数倀の衚を、䞊から1行ず぀積み䞊げお䜜る問題」** です。 +> なぜ「積み䞊げ」かずいうず、各行の内偎の倀は **盎䞊の巊ず右の倀を足すだけ** で決たるからです。 + +### 問題の芁件 + +䞎えられた敎数 `numRows` に察しお、パスカルの䞉角圢の最初の `numRows` 行を返したす。 + +``` +行0 [1] +行1 [1, 1] +行2 [1, 2, 1] +行3 [1, 3, 3, 1] +行4 [1, 4, 6, 4, 1] +``` + +**ルヌルは 2 ぀だけ** + +1. 各行の **䞡端は必ず `1`** +2. 内偎の芁玠は **真䞊の巊ず右の倀を足した倀**䟋行 2 の `2` = 行 1 の `1 + 1` + +**なぜこの問題が面癜いのか** +「前の行だけ芋れば次の行を䜜れる」ずいう局所的なルヌルが積み重なるず、矎しい䞉角圢ができ䞊がりたす。 +この「局所ルヌルの積み䞊げ」は、動的蚈画法郚分問題の答えを䜿っお党䜓の答えを組み立おる手法の入門ずしお最適な題材です。 + +### 制玄 + +| 項目 | 倀 | +| ---------------- | ------------------ | +| `numRows` の範囲 | `1 ≀ numRows ≀ 30` | +| 戻り倀の型 | `list[list[int]]` | + +> 📖 **この章で登堎した甚語** +> +> - **制玄**入力ずしお䞎えられる倀の範囲や条件のこず。䟋「numRows は 1 以䞊 30 以䞋」 +> - **動的蚈画法**問題を小さな郚分問題に分割し、その結果を蚘録しながら党䜓の答えを組み立おる手法 + +--- + +

アルゎリズム芁点TL;DR

+ +> 💡 **TL;DR ずは**Too Long; Didn't Read長くお読めない人向けの芁玄ずいう意味です。 +> ここでは「なんずなくこういう手順で解くんだな」ずいうむメヌゞを掎むこずが目暙です。 +> 各ステップの詳现は埌の章で説明したす。 + +- **戊略**`for` ルヌプで行を 1 行ず぀積み䞊げる。前の行だけ参照すれば次の行が䜜れるので、䜙分な情報を保持する必芁がない +- **デヌタ構造**`list[list[int]]`敎数のリストを芁玠ずする 2 次元リスト。むンデックスアクセスが頻繁なため `deque` より `list` が適切 +- **時間蚈算量**O(n²)。党芁玠数が `1 + 2 + ... + n = n(n+1)/2` なので避けられない䞋限 +- **空間蚈算量**O(n²)。党行をメモリに保持しお返すため +- **Python 最適化**内偎の芁玠はリスト内包衚蚘リストを 1 行で䜜る曞き方で䞀括生成。CPython のバむトコヌドレベルの最適化が効く + +> 📖 **この章で登堎した甚語** +> +> - **TL;DR**「長くお読めない人向けの芁玄」を意味する略語 +> - **バむトコヌド**Python のコヌドが実行される前に倉換される䞭間圢匏。`for` ルヌプより内包衚蚘の方が、専甚のバむトコヌド呜什を䜿うため高速 +> - **リスト内包衚蚘**`[匏 for 倉数 in むテラブル]` ずいう圢でリストを 1 行で䜜る曞き方 + +--- + +

図解

+ +> 💡 **Mermaid フロヌチャヌトの読み方** +> +> - **長方圢 `[]`**凊理ステップ䜕かをする +> - **ひし圢 `{}`**条件分岐Yes か No かで凊理が分かれる +> - **矢印 `-->`**凊理の流れの方向 +> +> 䞊から䞋ぞたたは巊から右ぞ読み進めおください。 + +### フロヌチャヌト + +この図は `generate(numRows)` 関数が内郚でどのような手順を螏むかを衚しおいたす。 +䞊から䞋ぞ読み進めるこずで、入力の怜蚌から行の積み䞊げ、結果の返华たでの流れが分かりたす。 + +```mermaid +flowchart TD + Start[Start generate numRows] + Start --> Validate{Valid input?} + Validate -- No --> Err[Raise TypeError or ValueError] + Validate -- Yes --> Init[Init triangle with row0 = 1] + Init --> Loop{row_index < numRows?} + Loop -- No --> Return[Return triangle] + Loop -- Yes --> BuildRow[Build current row] + BuildRow --> IsSmall{row_index <= 1?} + IsSmall -- Yes --> Fixed[Return fixed row 1 or 1 1] + IsSmall -- No --> Prev[Get prev row] + Prev --> Inner[Compute inner via list comprehension] + Inner --> Assemble[Assemble 1 + inner + 1] + Fixed --> Append[Append row to triangle] + Assemble --> Append + Append --> Increment[Increment row_index] + Increment --> Loop +``` + +**䞻芁ノヌドの意味** + +- `Start``generate(numRows)` の呌び出し入口 +- `Validate`ひし圢型チェックず範囲チェック。䞍正な入力をここで匟く +- `Init`結果リストを `[[1]]`1 行目で初期化する +- `Loop`ひし圢`row_index` が `numRows` に達するたで繰り返す終了条件の刀定 +- `BuildRow``_build_row()` ヘルパヌを呌び出す +- `IsSmall`ひし圢0 行目・1 行目は特殊凊理内偎の芁玠がない +- `Inner`リスト内包衚蚘で `prev[col-1] + prev[col]` を蚈算 +- `Assemble``[1] + inner + [1]` で行を完成させる +- `Append`完成した行を `triangle` に远加する + +--- + +### デヌタフロヌ図 + +この図は `numRows=5` のずき、各行のデヌタがどのように生成・蓄積されおいくかを衚しおいたす。 + +```mermaid +graph LR + subgraph Input + A[numRows = 5] + end + subgraph Row0 + B[row0 = 1] + end + subgraph Row1 + C[row1 = 1 1] + end + subgraph Row2 + D[prev = 1 1] + E[inner = 2] + F[row2 = 1 2 1] + D --> E + E --> F + end + subgraph Row3 + G[prev = 1 2 1] + H[inner = 3 3] + I[row3 = 1 3 3 1] + G --> H + H --> I + end + subgraph Row4 + J[prev = 1 3 3 1] + K[inner = 4 6 4] + L[row4 = 1 4 6 4 1] + J --> K + K --> L + end + A --> B + B --> C + C --> D + F --> G + I --> J + L --> M[Output triangle] +``` + +**䞻芁な流れの説明** + +- `Input → Row0`最初の行 `[1]` は固定倀なので蚈算䞍芁 +- `Rowi → prev`前の行がそのたた次の行の蚈算材料`prev`になる +- `prev → inner`隣り合う芁玠の和を内包衚蚘で䞀括蚈算 +- `inner → rowi``[1] + inner + [1]` で䞡端を远加しお行を完成させる + +--- + +> 💡 **代衚䟋でのトレヌス`numRows = 5`** + +``` +入力: numRows = 5 + +── 入力怜蚌 ── +isinstance(5, bool) → False +isinstance(5, int) → True +1 <= 5 <= 30 → 怜蚌通過 ✅ + +── ルヌプ ── + +[row_index = 0] + → row_index == 0 なので [1] を即返す + triangle = [[1]] + +[row_index = 1] + → row_index == 1 なので [1, 1] を即返す + triangle = [[1], [1,1]] + +[row_index = 2] + prev = [1, 1] + inner: col=1 → prev[0]+prev[1] = 1+1 = 2 + inner = [2] + row = [1] + [2] + [1] = [1, 2, 1] + triangle = [[1],[1,1],[1,2,1]] + +[row_index = 3] + prev = [1, 2, 1] + inner: col=1 → 1+2=3, col=2 → 2+1=3 + inner = [3, 3] + row = [1] + [3,3] + [1] = [1, 3, 3, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1]] + +[row_index = 4] + prev = [1, 3, 3, 1] + inner: col=1 → 1+3=4, col=2 → 3+3=6, col=3 → 3+1=4 + inner = [4, 6, 4] + row = [1] + [4,6,4] + [1] = [1, 4, 6, 4, 1] + triangle = [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + +出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅ +``` + +> 📖 **この章で登堎した甚語** +> +> - **フロヌチャヌト**凊理の手順を図圢ず矢印で衚したもの。ひし圢=条件分岐、長方圢=凊理 +> - **デヌタフロヌ図**デヌタがどのように倉換・移動するかを瀺す図 +> - **サブグラフ**フロヌチャヌトの䞭で関連する凊理をグルヌプ化した枠 + +--- + +

正しさのスケッチ

+ +> 💡 **初孊者向け補足** +> 「正しさのスケッチ」ずは、アルゎリズムが **垞に正しい答えを返すこずの根拠** を敎理したものです。 +> 数孊的な厳密な蚌明ではなく、「なぜ正しいず蚀えるか」の説明です。 + +### 䞍倉条件アルゎリズムが正しく動くために、ルヌプ䞭ずっず成り立ち続けるべき条件 + +> ルヌプの各むテレヌション繰り返しの 1 回分の開始時点で、 +> `triangle` には `row_index` 個の行が栌玍されおおり、それらはすべおパスカルの䞉角圢のルヌルを満たしおいる。 + +- `row_index = 0` のずき`triangle = [[1]]`。行 0 は定矩䞊 `[1]` なので成立 ✅ +- `row_index = k` で成立しおいるず仮定するず`_build_row` は `triangle[k-1]`前行から `prev[col-1] + prev[col]` を蚈算しお行 `k` を正しく構築する。よっお `row_index = k+1` でも成立 ✅ + +### 網矅性すべおのケヌスをもれなく凊理できおいるずいう保蚌 + +- `row_index == 0``[1]` を返す。長さ 1 の行に内偎の芁玠はなく、䞡端が `1` なのは定矩通り +- `row_index == 1``[1, 1]` を返す。長さ 2 の行に内偎の芁玠はなく、䞡端が `1` なのは定矩通り +- `row_index >= 2``[1] + inner + [1]` で構築。`inner` は `prev[col-1] + prev[col]` のすべおの `col` を蚈算するので抜け挏れなし + +### 基底条件再垰やルヌプの終了条件 + +- `row_index` は 0 始たりで `numRows` 未満の間だけ繰り返す +- 各行の長さは `row_index + 1` なので必ず正の倀。無限ルヌプにはならない + +### 終了性アルゎリズムが必ず有限ステップで終わるずいう保蚌 + +- `numRows ≀ 30` か぀各行の構築は O(k) で完了するため、党䜓は必ず有限ステップで終了する + +> 📖 **この章で登堎した甚語** +> +> - **䞍倉条件**アルゎリズムが正しく動くために、凊理䞭ずっず成り立ち続けるべき条件。「ルヌプ䞍倉条件」ずも呌ぶ +> - **網矅性**すべおのケヌスをもれなく凊理できおいるずいう保蚌 +> - **終了性**アルゎリズムが必ず有限ステップで終わるずいう保蚌 +> - **むテレヌション**ルヌプの 1 回分の繰り返し凊理のこず + +--- + +

蚈算量

+ +> 💡 **Big-O 蚘法の読み方** + +| 蚘法 | 意味 | 盎感的なむメヌゞ | +| ------------ | ---------------------- | --------------------------- | +| `O(1)` | 入力サむズによらず䞀定 | 蟞曞で盎接ペヌゞを開く | +| `O(n)` | 入力に比䟋しお増加 | リストを端から順に読む | +| `O(n log n)` | n よりやや速く増加 | 蟞曞を二分探玢で匕く × n 回 | +| `O(n²)` | 入力の 2 乗で増加 | 党ペアを総圓たりで確認する | + +### この問題の蚈算量 + +| 皮類 | 蚈算量 | 理由 | +| -------------- | ------ | -------------------------------------------------------- | +| **時間蚈算量** | O(n²) | 党芁玠数 = 1+2+
+n = n(n+1)/2。各芁玠を 1 床だけ蚈算する | +| **空間蚈算量** | O(n²) | 生成した党行を `triangle` リストに保持しお返すため | + +### なぜ O(n²) を䞋回れないのか + +出力自䜓が `n(n+1)/2` 個の芁玠を持぀ため、それらを生成するだけで O(n²) の時間が必芁です。 +どんなに賢いアルゎリズムを䜿っおも、この䞋限どうしおも避けられない蚈算量の最䜎ラむンは超えられたせん。 + +### Pure vs in-place の比范 + +| 方匏 | 空間蚈算量 | 説明 | +| ---------------------- | ---------- | ------------------------------------------------------------ | +| **Pure今回の実装** | O(n²) | 党行を新しいリストずしお返す。元のデヌタを倉曎しない | +| **in-place** | - | この問題は「党行を返す」のが仕様なので in-place の䜙地はない | + +> 📖 **この章で登堎した甚語** +> +> - **時間蚈算量**入力の倧きさに察しお凊理にかかる手間がどう増えるかの目安 +> - **空間蚈算量**凊理䞭に䜿うメモリ量がどう増えるかの目安 +> - **例限**どんなアルゎリズムを䜿っおも越えられない蚈算量の最䜎ラむン +> - **Pure**入力を倉曎せず新しいデヌタを返す操䜜。副䜜甚がなく安党 + +--- + +

Python 実装

+ +> 💡 **実装の骚栌党䜓像の把握** +> コヌドを読む前に、凊理の流れを箇条曞きで確認したしょう。 +> +> 1. 入力 `numRows` の **型チェック**`bool` ず `int` の区別に泚意ず **範囲チェック**1〜30 以倖を匟く +> 2. 結果リスト `triangle` を空で甚意する +> 3. `for` ルヌプで `row_index = 0` から `numRows - 1` たで繰り返す +> 4. 各むテレヌションで `_build_row()` を呌び、返っおきた行を `triangle` に远加する +> 5. `_build_row()` 内0 行目・1 行目は固定倀を返す。2 行目以降は `prev` を参照しおリスト内包衚蚘で蚈算する +> 6. ルヌプ終了埌に `triangle` を返す + +```python +from __future__ import annotations + +# TYPE_CHECKING はpylance静的型チェッカヌが型情報を解析するずきだけ True になる。 +# 実行時には False なので、型ヒント専甚のむンポヌトは実行コストれロ。 +from typing import TYPE_CHECKING, Any + + +class Solution: + """ + LeetCode 118: Pascal's Triangle + + パスカルの䞉角圢の最初の numRows 行を生成しお返す。 + 各行は前の行だけを参照しお O(k) で構築するk = 行のむンデックス。 + 党䜓の時間蚈算量: O(n²) / 空間蚈算量: O(n²) n = numRows + """ + + def generate(self, numRows: int) -> list[list[int]]: + """ + パスカルの䞉角圢を生成しお返す業務開発版。 + + Args: + numRows: 生成する行数。制玄: 1 <= numRows <= 30 + + Returns: + 各行を list[int] で衚した 2 次元リスト + + Raises: + TypeError: numRows が int 型でない堎合bool を含む + ValueError: numRows が 1 未満たたは 30 超の堎合 + + Time Complexity: O(n²) + Space Complexity: O(n²) + """ + # ── 入力怜蚌型チェック ────────────────────────────────────── + # Python では bool が int のサブクラスのため isinstance(True, int) → True になる。 + # True/False が numRows ずしお枡されおも気づかないバグを防ぐため、先に bool を匟く。 + if isinstance(numRows, bool) or not isinstance(numRows, int): + raise TypeError( + f"numRows must be an int, got: {type(numRows).__name__}" + ) + + # ── 入力怜蚌範囲チェック ──────────────────────────────────── + # 制玄「1 <= numRows <= 30」の範囲倖を匟く。 + # ここで匟かないず埌続のリストアクセスで意図しない動䜜が起きる可胜性がある。 + if numRows < 1 or numRows > 30: + raise ValueError( + f"numRows must be between 1 and 30, got: {numRows}" + ) + + # ── 結果栌玍甚リスト ──────────────────────────────────────────── + # list[list[int]] = 「敎数のリスト」を芁玠ずする 2 次元リスト型泚釈。 + # pylance がこの倉数の型を正確に把握できるよう明瀺しおいる。 + triangle: list[list[int]] = [] + + # ── 行を 1 行ず぀積み䞊げる ───────────────────────────────────── + for row_index in range(numRows): + # _build_row() に「これたでの䞉角圢」ず「今䜜りたい行番号」を枡す。 + # 前の行の参照は _build_row() 内で行うため、ここはシンプルに保おる。 + current_row = self._build_row(triangle, row_index) + triangle.append(current_row) + + return triangle + + def _build_row( + self, triangle: list[list[int]], row_index: int + ) -> list[int]: + """ + 指定した行むンデックスの行を構築しお返すヘルパヌ関数。 + + Args: + triangle: これたでに構築した䞉角圢。前行の参照に䜿う。 + row_index: 今から構築する行のむンデックス0 始たり + + Returns: + 新しく構築した行list[int] + """ + # ── 基底条件 10 行目 ───────────────────────────────────────── + # パスカルの䞉角圢の定矩により、最初の行は [1] ず決たっおいる。 + # 前の行が存圚しないためここで早期リタヌンする。 + if row_index == 0: + return [1] + + # ── 基底条件 21 行目 ───────────────────────────────────────── + # 1 行目も [1, 1] ず決たっおいる。内偎の芁玠が 1 ぀もないケヌス。 + # 内偎芁玠の蚈算匏 prev[col-1]+prev[col] は col=1..0 → 範囲が空になる + if row_index == 1: + return [1, 1] + + # ── 2 行目以降前の行を参照しお内偎を蚈算する ────────────────── + # triangle[row_index - 1] が前の行。 + # list[int] ず型泚釈を付けるこずで pylance が prev ぞの操䜜を型チェックできる。 + prev: list[int] = triangle[row_index - 1] + + # リスト内包衚蚘リストを 1 行で䜜る曞き方で内偎の芁玠を䞀括蚈算する。 + # 「なぜ for ルヌプではなく内包衚蚘か」 + # CPython は内包衚蚘専甚の最適化されたバむトコヌド呜什LIST_APPENDを䜿う。 + # 玠朎な for + append() より高速に動䜜するため。 + # range(1, row_index) で先頭ず末尟をスキップ䞡端は必ず 1 なので埌で远加。 + inner: list[int] = [ + prev[col - 1] + prev[col] # 真䞊の巊 + 真䞊の右 + for col in range(1, row_index) + ] + + # [1] + inner + [1] でリストを結合しお完成した行にする。 + # Python のリスト結合は新しいリストを生成するが、行の長さは最倧 30 なので問題ない。 + return [1] + inner + [1] +``` + +--- + +### 競技プログラミング版LeetCode 提出甚最短実装 + +```python +class Solution: + def generate(self, numRows: int) -> list[list[int]]: + # 1 行目を盎接入れお初期化する + tri: list[list[int]] = [[1]] + + # 2 行目以降をルヌプで積み䞊げる0 行目は初期化枈みなので range(1, ...) から + for i in range(1, numRows): + # tri[-1] は「tri リストの末尟 = 盎前の行」を O(1) で取埗する Python の蚘法 + p = tri[-1] + + # 䞡端の [1] ず内包衚蚘で蚈算した内偎を 1 行で結合する + tri.append([1] + [p[j - 1] + p[j] for j in range(1, i)] + [1]) + + return tri +``` + +--- + +> 💡 **コヌドの動䜜トレヌス`numRows = 5`** + +``` +入力: numRows = 5 + +── 業務開発版の流れ ── + +[入力怜蚌] +isinstance(5, bool) → Falsebool チェック通過 +isinstance(5, int) → True型チェック通過 +1 <= 5 <= 30 → 範囲チェック通過 ✅ +triangle = []空リストで初期化 + +[row_index = 0] +_build_row([], 0) → row_index == 0 → return [1] +triangle = [[1]] + +[row_index = 1] +_build_row([[1]], 1) → row_index == 1 → return [1, 1] +triangle = [[1], [1,1]] + +[row_index = 2] +_build_row(triangle, 2): + prev = [1, 1] + inner = [prev[0]+prev[1]] = [1+1] = [2] ← col=1 の 1 ステップのみ + return [1] + [2] + [1] = [1, 2, 1] +triangle = [[1],[1,1],[1,2,1]] + +[row_index = 3] +_build_row(triangle, 3): + prev = [1, 2, 1] + inner: + col=1 → prev[0]+prev[1] = 1+2 = 3 + col=2 → prev[1]+prev[2] = 2+1 = 3 + inner = [3, 3] + return [1] + [3,3] + [1] = [1, 3, 3, 1] +triangle = [[1],[1,1],[1,2,1],[1,3,3,1]] + +[row_index = 4] +_build_row(triangle, 4): + prev = [1, 3, 3, 1] + inner: + col=1 → prev[0]+prev[1] = 1+3 = 4 + col=2 → prev[1]+prev[2] = 3+3 = 6 + col=3 → prev[2]+prev[3] = 3+1 = 4 + inner = [4, 6, 4] + return [1] + [4,6,4] + [1] = [1, 4, 6, 4, 1] +triangle = [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + +最終出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅ +``` + +> 📖 **この章で登堎した甚語** +> +> - **`from __future__ import annotations`**型ヒントを文字列ずしお扱うようにする宣蚀。クラス自身を型ヒントに䜿う「前方参照」を解決できる +> - **`TYPE_CHECKING`**`from typing import TYPE_CHECKING` で䜿える定数。pylance が解析するずきだけ `True` になり、実行時は `False`。型専甚のむンポヌトを実行コストれロで曞くためのテクニック +> - **`isinstance()`**倉数がある型かどうかを調べる組み蟌み関数。C 蚀語実装のため高速 +> - **`bool` は `int` のサブクラス**Python では `True` が `1`、`False` が `0` ずしお扱われる。`isinstance(True, int)` が `True` を返すため、`bool` を先にチェックする順番が重芁 +> - **リスト内包衚蚘**`[匏 for 倉数 in むテラブル]` ずいう圢でリストを 1 行で䜜る曞き方。CPython 専甚の最適化呜什`LIST_APPEND`が䜿われるため `for + append()` より高速 +> - **`tri[-1]`**Python 固有の負のむンデックス蚘法。末尟芁玠を O(1) で取埗できる + +--- + +

CPython 最適化ポむント

+ +> 💡 **この章では「同じ凊理でも Python の曞き方によっお速さが倉わる理由」を説明したす。** +> 最適化は「最適化前のコヌド → 最適化埌のコヌド → なぜ速いか」の 3 点セットで説明したす。 + +### ポむント 1リスト内包衚蚘 vs for ルヌプ + +内偎の芁玠を蚈算する郚分を比范したす。 + +```python +# ── 最適化前for ルヌプで 1 芁玠ず぀远加 ── +inner: list[int] = [] +for col in range(1, row_index): + inner.append(prev[col - 1] + prev[col]) + +# ── 最適化埌リスト内包衚蚘で䞀括生成 ── +inner: list[int] = [ + prev[col - 1] + prev[col] + for col in range(1, row_index) +] +# なぜ速いか +# CPython はリスト内包衚蚘をコンパむルするずき、 +# ルヌプ専甚の最適化されたバむトコヌド呜什「LIST_APPEND」を䜿う。 +# 䞀方の for + append() は毎回「self.inner.append」ずいう +# 属性アクセス蟞曞怜玢が発生するため、その分だけ遅くなる。 +``` + +### ポむント 2`tri[-1]` による末尟アクセス + +競技プログラミング版で䜿っおいるテクニックです。 + +```python +# ── 最適化前むンデックスを明瀺しお前行を取埗 ── +prev = triangle[len(triangle) - 1] + +# ── 最適化埌Python の負のむンデックスを䜿う ── +prev = tri[-1] +# なぜ速いか +# Python の list は末尟から数えるむンデックス負倀を O(1) でサポヌトしおいる。 +# len() の蚈算ず匕き算が䞍芁になるため、コヌドが短く・速くなる。 +``` + +### ポむント 3`[1] + inner + [1]` によるリスト結合 + +```python +# ── 最適化前先頭・末尟を insert/append で远加 ── +inner.insert(0, 1) # O(n)先頭ぞの挿入は党芁玠を右にシフトするため遅い +inner.append(1) # O(1)末尟ぞの远加は速い + +# ── 最適化埌リスト結合挔算子 + を䜿う ── +row = [1] + inner + [1] +# なぜこちらが良いか +# list.insert(0, x) は先頭ぞの挿入のため O(n) かかる党芁玠を右に移動するから。 +# [1] + inner + [1] は新しいリストを生成するが、行の長さは最倧 30 なので +# O(30) = O(1) ずみなせる。たた insert() の O(n) を回避できる。 +``` + +> 📖 **この章で登堎した甚語** +> +> - **バむトコヌド**Python コヌドが CPython 内郚で倉換される䞭間衚珟。`LIST_APPEND` はリスト内包衚蚘専甚の高速呜什 +> - **属性アクセス**`obj.method` のようにオブゞェクトのプロパティを参照する操䜜。CPython 内郚では蟞曞dictを䜿っお名前を怜玢するため、毎回コストが発生する +> - **`list.insert(0, x)`**リストの先頭に芁玠を挿入する操䜜。党芁玠を右にシフトするため O(n) になる +> - **負のむンデックス**`list[-1]` のように末尟から数える Python 固有の蚘法。`list[len(list)-1]` ず同じ意味 + +--- + +

゚ッゞケヌスず怜蚌芳点

+ +> 💡 **初孊者向け補足** +> ゚ッゞケヌス境界的な条件の入力を芋萜ずすず、普通のテストは通るのに +> 特定の入力でだけバグが発生したす。代衚的な゚ッゞケヌスを確認したしょう。 + +| ゚ッゞケヌス | 入力䟋 | 期埅出力 | なぜ問題になりうるか | +| ------------------------- | ------------ | --------------------- | ----------------------------------------------------------------------------------------------------- | +| **最小倀** | `numRows=1` | `[[1]]` | ルヌプが 1 回しか回らない。行 0 の特殊凊理が正しく動くか確認が必芁 | +| **最倧倀** | `numRows=30` | 30 行の䞉角圢 | 最倧 465 芁玠を生成する。タむムアりトや MemoryError が起きないか | +| **行 2 の最初の内偎芁玠** | `numRows=3` | `[[1],[1,1],[1,2,1]]` | `inner` の長さが 1 になる。範囲が `range(1, 2)` で正しく動くか確認 | +| **型゚ラヌ文字列** | `"5"` | `TypeError` | `isinstance()` チェックがなければ埌続でクラッシュする | +| **型゚ラヌbool** | `True` | `TypeError` | `bool` は `int` のサブクラスなので `isinstance(True, int)` が `True` を返す。先に bool チェックが必芁 | +| **範囲倖0 以䞋** | `numRows=0` | `ValueError` | ルヌプが 0 回回り、空リストが返る。仕様䞊 `numRows >= 1` なので゚ラヌにすべき | +| **範囲倖31 以䞊** | `numRows=31` | `ValueError` | 制玄䞊限を超えた入力。゚ラヌにすべき | +| **浮動小数点数** | `5.0` | `TypeError` | `isinstance(5.0, int)` は `False` なので型゚ラヌになるが、意図が明確になるよう怜蚌メッセヌゞを出す | + +```python +from typing import Any + +sol = Solution() + +# 最小倀 +assert sol.generate(1) == [[1]] + +# 2 行 +assert sol.generate(2) == [[1], [1, 1]] + +# 代衚䟋 +assert sol.generate(5) == [[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]] + +# 最倧倀30 行生成できるこず・先頭行ず最終行の䞡端が 1 であるこず +result_30 = sol.generate(30) +assert len(result_30) == 30 +assert result_30[0] == [1] +assert result_30[-1][0] == 1 +assert result_30[-1][-1] == 1 + +# 型゚ラヌ文字列 +try: + sol.generate("5") # type: ignore[arg-type] + assert False, "TypeError が発生するべき" +except TypeError: + pass + +# 型゚ラヌboolTrue は 1 ずしお扱われるが仕様䞊゚ラヌにする +try: + sol.generate(True) # type: ignore[arg-type] + assert False, "TypeError が発生するべき" +except TypeError: + pass + +# 範囲倖0 以䞋 +try: + sol.generate(0) + assert False, "ValueError が発生するべき" +except ValueError: + pass + +# 範囲倖31 以䞊 +try: + sol.generate(31) + assert False, "ValueError が発生するべき" +except ValueError: + pass +``` + +> 📖 **この章で登堎した甚語** +> +> - **゚ッゞケヌス**空のリスト・最小倀・最倧倀など、境界的な条件の入力 +> - **境界倀**制玄の䞊限・䞋限にあたる倀。䟋`numRows=1` や `numRows=30` +> - **`TypeError`**型が䞍正な堎合に投げる゚ラヌ。「敎数を枡すべきずころに文字列を枡した」など +> - **`ValueError`**型は正しいが倀の範囲が䞍正な堎合に投げる゚ラヌ。「1〜30 の範囲倖の敎数」など + +--- + +

FAQ

+ +> 💡 **FAQFrequently Asked Questionsずは「よくある質問ず回答」のこずです。** +> 初孊者が぀たずきやすいポむントを Q&A 圢匏でたずめたした。 +> 各回答は「結論 → 理由 → 補足具䜓䟋」の順で曞いおいたす。 + +--- + +**Q1. なぜ `deque` を䜿わずに `list` を䜿うのですか** + +**結論**この問題では `list` の方が適切です。 + +**理由**`deque`前埌から出し入れできる䞡端キュヌが有効なのは「先頭ぞの远加・削陀が頻繁なずき」です。 +`list.pop(0)` や `list.insert(0, x)` は O(n) かかりたすが、`deque.popleft()` や `deque.appendleft()` は O(1) です。 +しかしこの問題では先頭ぞの挿入は `[1]` ずの結合で 1 回だけ行い、その埌はむンデックスアクセス`prev[col]`が䞭心です。 +`deque` のむンデックスアクセスは O(n) なのに察し、`list` は O(1) です。そのため `list` が向いおいたす。 + +**補足**`deque` を䜿うべき堎面の䟋 → BFS幅優先探玢での先頭からの取り出し、スラむディングりィンドりでの先頭削陀 + +--- + +**Q2. `bool` の型チェックを `isinstance(numRows, int)` の前に眮く理由は䜕ですか** + +**結論**`bool` は Python の `int` のサブクラスなので、順番を間違えるず `True/False` が敎数ずしお通過しおしたいたす。 + +**理由**Python では `True == 1`、`False == 0` です。そのため `isinstance(True, int)` は `True` を返したす。 +もし `isinstance(numRows, int)` を先にチェックするず、`True` が 1 ずしお扱われ怜蚌を通過しおしたいたす。 +`bool` を先にチェックするこずで「`True` は `int` ではなく `bool` だ」ず正しく匟けたす。 + +```python +# ❌ 間違った順番bool が通過しおしたう +if not isinstance(numRows, int): + raise TypeError(...) +# → isinstance(True, int) == True なので True が通過する + +# ✅ 正しい順番bool を先に匟く +if isinstance(numRows, bool) or not isinstance(numRows, int): + raise TypeError(...) +# → isinstance(True, bool) == True なので True を匟ける +``` + +--- + +**Q3. なぜ行 0 ず行 1 を特殊ケヌスずしお分けるのですか** + +**結論**行 0 ず行 1 は「内偎の芁玠」が存圚せず、汎甚ロゞックを圓おはめるず蚈算が空振りするからです。 + +**理由**汎甚ロゞックである `[prev[col-1] + prev[col] for col in range(1, row_index)]` は +`row_index = 0` のずき `range(1, 0)` → 空のむテラブル、`row_index = 1` のずき `range(1, 1)` → 空のむテラブルになりたす。 +空のむテラブルに `[1] + [] + [1] = [1, 1]` ずなり行 1 は正しく動きたすが、行 0 は `triangle[-1]` ぞのアクセスで +`IndexError`むンデックス゚ラヌが発生したす`triangle` がただ空のため。 +これを安党に凊理するために早期リタヌンを蚭けおいたす。 + +``` +row_index=0: range(1, 0) → 空 → [1] + [] + [1] でも良さそうだが + 前の行 triangle[-1] が存圚しないので IndexError になる + → 早期リタヌンで [1] を返す +row_index=1: range(1, 1) → 空 → [1] + [] + [1] = [1, 1] → 正しい + でも前の行 [1] を参照するのでロゞック的には問題なし + → 明瀺的に特殊ケヌスにするこずで意図を明確にする +``` + +--- + +**Q4. `[1] + inner + [1]` でリストを結合するずき、毎回新しいリストが䜜られるのでは** + +**結論**はい、新しいリストが䜜られたす。しかしこの問題では問題になりたせん。 + +**理由**Python の `+` 挔算子はリストを結合した **新しいリスト** を返したす元のリストは倉曎したせん。 +行の長さは最倧 `numRows + 1 = 31` 芁玠なので、1 回の結合コストは O(31) ≈ O(1) ずみなせたす。 +党行で合蚈しおも O(n²) の定数倍に収たり、蚈算量に圱響したせん。 + +**補足**もし行の長さが非垞に倧きい堎合䟋10 䞇芁玠は `[1] + inner + [1]` が O(n) になるため、 +`inner.insert(0, 1)` ず `inner.append(1)` を分けた方がメモリ効率が良くなりたす。 +ただしこの問題では `numRows ≀ 30` なので気にする必芁はありたせん。 + +--- + +**Q5. 競技プログラミング版ず業務開発版、どちらを遞ぶべきですか** + +**結論**LeetCode ぞの提出なら競技プログラミング版、チヌム開発や長期メンテなら業務開発版を遞びたす。 + +| 刀断軞 | 競技プログラミング版 | 業務開発版 | +| ---------------------------------- | -------------------- | --------------------------- | +| **コヌドの短さ** | ◎ | △ | +| **実行速床** | ◎ | ○同等だが怜蚌コストあり | +| **型安党性** | △最小限 | ◎ | +| **゚ラヌの分かりやすさ** | ✗省略 | ◎ | +| **埌から読んだずきの理解しやすさ** | △ | ◎ | + +**補足**LeetCode では入力が問題の制玄を満たすこずが保蚌されおいるため、型チェックや範囲チェックは省略できたす。 +䞀方、実際のシステム開発では「誰が䜕を枡しおくるか分からない」ため、怜蚌が重芁です。 + +> 📖 **この章で登堎した甚語** +> +> - **FAQ**Frequently Asked Questions の略。よくある質問ず回答のこず +> - **`IndexError`**リストや文字列の範囲倖の芁玠にアクセスしようずしたずきの゚ラヌ。䟋長さ 0 のリストに `list[0]` でアクセスする +> - **むテラブル**`for` ルヌプで繰り返せるオブゞェクトの総称。リスト・タプル・`range` など +> - **早期リタヌン**関数の先頭で特殊なケヌスを刀定し、すぐに `return` するこずで埌続の凊理を単玔に保぀テクニック diff --git a/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html new file mode 100644 index 0000000..8bfe72a --- /dev/null +++ b/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html @@ -0,0 +1,2001 @@ + + + + + + LeetCode 118 — Pascal's Triangle + + + + + + + + + + + + + + + + +
+ + + + +
+

+ アルゎリズム抂芁 +

+ +
+

+ 💡 + この問題を䞀蚀で蚀うず「䞉角圢の圢に数倀を䞊べ、䞊から1行ず぀積み䞊げお完成させる問題」 +

+

+ 各行の倀は「真䞊の巊ず右の倀を足すだけ」で決たりたす。この「局所ルヌルの積み重ね」は + 動的蚈画法郚分問題の答えを再利甚しお党䜓を解く技法の最良な入門䟋です。 +

+
+ +
+

+ ⚠ なぜ単玔な方法では解けないのか +

+
    +
  • + 各行は前の行の倀がなければ蚈算できない。行をたたいだ䟝存関係がある。 +
  • +
  • + 党行を保持しお返す必芁があるため、出力サむズ自䜓が O(n²) + になる。これは避けられない䞋限。 +
  • +
  • + Python では + bool が + int + のサブクラスなので、型チェックの順番を誀るずバグになる詳现は FAQ + 参照。 +
  • +
+
+ +
+
+
O(n²)
+
時間蚈算量
+
+
+
O(n²)
+
空間蚈算量
+
+
+
+ 1 â‰€ n â‰€ 30 +
+
numRows の範囲
+
+
+
+ list[list[int]] +
+
戻り倀の型
+
+
+ +
+
+

+ 📥 入力 / 📀 出力の䟋 +

+
+
# 入力
+
numRows = 5
+
# 出力
+
[[1],
+
 [1, 1],
+
 [1, 2, 1],
+
 [1, 3, 3, 1],
+
 [1, 4, 6, 4, 1]]
+
+

+ ✅ なぜこれが正解か行2の + 2 は行1の + 1+1、 行3の + 3 は行2の + 1+2 および + 2+1。すべお定矩通り。 +

+
+
+

+ 📐 パスカルの䞉角圢のルヌル2぀だけ +

+
+
+ ルヌル 1 + 各行の䞡端は必ず 1 +
+
+ ルヌル 2 + 内偎の芁玠 = 真䞊の巊 + 真䞊の右
+ 䟋行2の 2 = + 行1の 1 + 1 +
+
+
+
+
+ + +
+

+ ステップバむステップ解説 +

+

+ numRows = 5 を䟋に、アルゎリズムの各ステップを远いたす。 +

+
+
+ + +
+

+ Python 実装 +

+ +
+

+ 📋 このコヌドの構造先に党䜓像を把握しよう +

+
    +
  1. 入力の怜蚌型チェックbool を先に匟くず範囲チェック1〜30
  2. +
  3. + 結果リスト + triangle + を空で初期化し、for + ルヌプで行を積み䞊げる +
  4. +
  5. + 各行は + _build_row() + ヘルパヌで構築行0・行1は固定倀を返す +
  6. +
  7. + 行2以降前行を参照し、リスト内包衚蚘で内偎を蚈算しお + [1]+inner+[1] + で完成 +
  8. +
+
+ +

+ ▾ 業務開発版型怜蚌・コメント付き +

+
from __future__ import annotations
+
+
+class Solution:
+    """LeetCode 118: Pascal's Triangle — 行の積み䞊げ法"""
+
+    def generate(self, numRows: int) -> list[list[int]]:
+        # ── 入力怜蚌型チェック ────────────────────────────────────
+        # Python では bool が int のサブクラスなので先に bool を匟く
+        if isinstance(numRows, bool) or not isinstance(numRows, int):
+            raise TypeError(f"numRows must be int, got: {type(numRows).__name__}")
+
+        # ── 入力怜蚌範囲チェック ──────────────────────────────────
+        if numRows < 1 or numRows > 30:
+            raise ValueError(f"numRows must be 1‒30, got: {numRows}")
+
+        # ── 結果栌玍甚リスト ──────────────────────────────────────────
+        triangle: list[list[int]] = []
+
+        # ── 行を 1 行ず぀積み䞊げる ───────────────────────────────────
+        for row_index in range(numRows):
+            current_row = self._build_row(triangle, row_index)
+            triangle.append(current_row)
+
+        return triangle
+
+    def _build_row(self, triangle: list[list[int]], row_index: int) -> list[int]:
+        # 基底条件1行0 は [1] 固定前行が存圚しないので早期リタヌン
+        if row_index == 0:
+            return [1]
+
+        # 基底条件2行1 は [1, 1] 固定内偎の芁玠が存圚しない
+        if row_index == 1:
+            return [1, 1]
+
+        # 行2以降前の行を参照しお内偎の芁玠をリスト内包衚蚘で蚈算
+        prev: list[int] = triangle[row_index - 1]
+
+        # CPython の LIST_APPEND 呜什が効くため、for+append より高速
+        inner: list[int] = [
+            prev[col - 1] + prev[col]   # 真䞊の巊 + 真䞊の右
+            for col in range(1, row_index)
+        ]
+
+        return [1] + inner + [1]
+
+ +
+

+ ▶ 入力䟋 numRows = 5 での動䜜トレヌス +

+
+入力: numRows = 5
+
+[怜蚌] isinstance(5, bool)→False, isinstance(5, int)→True, 1≀5≀30 ✅
+
+[row_index=0] _build_row([], 0)  → [1]             triangle=[[1]]
+[row_index=1] _build_row(.., 1)  → [1,1]            triangle=[[1],[1,1]]
+[row_index=2] prev=[1,1]
+              inner: col=1 → 1+1=2  →  inner=[2]
+              return [1]+[2]+[1] = [1,2,1]            triangle=[[1],[1,1],[1,2,1]]
+[row_index=3] prev=[1,2,1]
+              inner: col=1→1+2=3, col=2→2+1=3  →  inner=[3,3]
+              return [1,3,3,1]                        triangle=[..,[1,3,3,1]]
+[row_index=4] prev=[1,3,3,1]
+              inner: col=1→1+3=4, col=2→3+3=6, col=3→3+1=4  →  inner=[4,6,4]
+              return [1,4,6,4,1]                      triangle=[..,[1,4,6,4,1]]
+
+出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅
+
+ +

+ ▾ 競技プログラミング版LeetCode 提出甚・最短実装 +

+
class Solution:
+    def generate(self, numRows: int) -> list[list[int]]:
+        tri: list[list[int]] = [[1]]
+        for i in range(1, numRows):
+            p = tri[-1]          # tri[-1] → 末尟行を O(1) で取埗Python の負むンデックス
+            tri.append([1] + [p[j-1] + p[j] for j in range(1, i)] + [1])
+        return tri
+
+
+ + +
+

+ 凊理フロヌチャヌト +

+ +
+

+ 🗺 フロヌチャヌトの読み方 +

+
+
+ + + + 楕円緑 開始・終了 +
+
+ + + + 四角青 凊理ステップ +
+
+ + + + ひし圢黄 条件分岐 +
+
+ はい + いいえ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + 開始 + + + + + + + + + 入力怜蚌 + + + (型・範囲チェック) + + + + + + TypeError / + + + ValueError + + + + + No + + + + + Yes + + + + + triangle = [] を初期化 + + + (結果を栌玍する 2 次元リスト) + + + + + + + + + row_index < numRows ? + + + (ルヌプ継続の刀定) + + + + + + triangle + + + を返す + + + + + No + + + + + Yes + + + + + _build_row() 呌び出し + + + (珟圚の行番号を枡す) + + + + + + + + + row_index ≀ 1 ? + + + (基底条件の刀定) + + + + + + [1] たたは + + + [1, 1] を返す + + + + + Yes + + + + + + + + No + + + + + prev = triangle[row_index − 1] + + + (前の行を参照する) + + + + + + + + + リスト内包衚蚘で inner を蚈算 + + + prev[c−1] + prev[c] の党おの c + + + + + + + + + row = [1] + inner + [1] + + + (䞡端に 1 を付けお行を完成) + + + + + + + + + triangle.append(row) + + + (完成した行を䞉角圢に远加) + + + + + + + + + row_index += 1 + + + (次の行ぞ進む) + + + + + 繰り返す + +
+ +
+

+ 🔎 入力䟋 numRows = 5 でのフロヌ远跡 +

+
    +
  1. + 「開始」→ 入力怜蚌isinstance + で型ず範囲を確認→ 怜蚌通過 +
  2. +
  3. + triangle = [] + を初期化。ルヌプに入る。 +
  4. +
  5. + row_index=0: ルヌプ条件 0<5 → Yes → + _build_row + → row_index≀1 → Yes → + [1] を + append。 +
  6. +
  7. + row_index=1: 同様に + [1,1] を + append。 +
  8. +
  9. + row_index=2〜4: row_index≀1 → No → prev 参照 → inner 蚈算 → + [1]+inner+[1] + → append → row_index++。 +
  10. +
  11. + row_index=5: ルヌプ条件 5<5 → No → + triangle + を返す。 +
  12. +
+
+
+ + +
+

+ 蚈算量分析 +

+ +
+

+ 📖 Big-O 蚘法の読み方入力 n + が倧きくなるに぀れ凊理時間がどう倉わるかの目安 +

+
+
+
O(1)
+
+ 垞に䞀定
䟋蟞曞の盎接匕き +
+
+
+
O(n)
+
+ 入力に比䟋
䟋リストを1回走査 +
+
+
+
O(n log n)
+
+ n より少し倚い
䟋゜ヌトアルゎリズム +
+
+
+
O(n²)
+
+ 入力の2乗
䟋二重ルヌプ総圓たり +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ 皮類 + + 蚈算量 + + 理由 +
+ 時間蚈算量 + + O(n²) + + 党芁玠数 = 1+2+
+n = n(n+1)/2。各芁玠を1床だけ蚈算する。 +
+ 空間蚈算量 + + O(n²) + + 党行を + triangle + に保持しお返すため。 +
+ 1行あたり + + O(k) + + k 行目の構築は k 個の芁玠を蚈算するだけk は行むンデックス。 +
+
+ +
+

+ 🔍 なぜ O(n²) になるのか、そしお䞋回れないのか +

+

+ 行 k の芁玠数は k+1 個なので、党芁玠数は 1+2+3+
+n = n(n+1)/2 ≈ n²/2 + です。これは Big-O 衚蚘で O(n²) になりたす。 + 重芁なのは「出力自䜓が n²/2 + 個の芁玠を持぀」ずいう点です。どんなに賢いアルゎリズムを䜿っおも、 + 出力を生成するだけで O(n²) の時間が必芁になりたす。この O(n²) + は䞋限どうしおも䞋回れないコストであり、 + 本実装はその䞋限を達成しおいたす。 +

+
+ +
+

+ 📊 numRows ごずの芁玠数の増え方 +

+ + + + + + + + + + + + + + + + + + + + + +
+ numRows (n) + 15102030
+ 党芁玠数 + + 1 + + 15 + + 55 + + 210 + + 465 +
+
+
+ + +
+

+ 📖 甚語集 +

+

+ このペヌゞで登堎した専門甚語をたずめたした。分からない蚀葉が出おきたずきに参照しおください。五十音順 +

+
+
+ + ▶ むテラブル + +
+ for + ルヌプで繰り返せるオブゞェクトの総称。 リスト・タプル・range() + など。 䟋range(1, 3) + は + 1, 2 + を順に返すむテラブル。 +
+
+ +
+ + ▶ むテレヌション + +
+ ルヌプの1回分の繰り返し凊理のこず。for i in range(5) + は5回むテレヌションする。 +
+
+ +
+ + ▶ 䞋限かげん + +
+ どんなアルゎリズムを䜿っおも越えられない蚈算量の最䜎ラむン。 + この問題では出力自䜓が O(n²) 個の芁玠を持぀ため、O(n²) が䞋限になる。 +
+
+ +
+ + ▶ + 基底条件きおいじょうけん + +
+ 再垰やルヌプの終了条件、たたは特殊ケヌスを凊理する最初の条件。 + この問題では行0[1]ず行1[1,1]が基底条件。 + 内偎の芁玠が存圚しないため、汎甚ロゞックずは別に凊理する。 +
+
+ +
+ + ▶ + 空間蚈算量くうかんけいさんりょう + +
+ 凊理䞭に䜿うメモリ量が入力 n に察しおどう倉化するかの目安。 + 蟞曞に䟋えるず「探偵がメモを取るためのノヌトの枚数」。 + この問題では党行を保存するため O(n²)。 +
+
+ +
+ + ▶ + 時間蚈算量じかんけいさんりょう + +
+ 入力の倧きさ n に察しお凊理にかかる手間がどう増えるかの目安。 「n + が2倍になったら凊理時間は䜕倍か」を衚す Big-O 蚘法で衚珟する。 O(n²) + は「n が2倍になるず凊理は4倍になる」ずいう意味。 +
+
+ +
+ + ▶ + 動的蚈画法どうおきけいかくほう + +
+ 問題を小さな郚分問題に分割し、その結果を再利甚しながら党䜓の答えを組み立おる手法。 + 料理に䟋えるず「昚日䜜ったスヌプのだしを今日の料理に䜿い回す」むメヌゞ。 + この問題では「前の行郚分問題の答えを䜿っお次の行を䜜る」のが動的蚈画法に圓たる。 +
+
+ +
+ + ▶ + 䞍倉条件ふぞんじょうけん + +
+ アルゎリズムが正しく動くために、ルヌプ䞭ずっず成り立ち続けるべき条件ルヌプ䞍倉条件ずも蚀う。 + この問題では「ルヌプ開始時に + triangle + には正しいパスカルの行が入っおいる」が䞍倉条件。 +
+
+ +
+ + ▶ バむトコヌド + +
+ Python の゜ヌスコヌドが実行前に倉換される䞭間圢匏。 CPython + はリスト内包衚蚘を + LIST_APPEND + ずいう専甚の最適化呜什にコンパむルするため、 通垞の + for + append() + より高速に動䜜する。 +
+
+ +
+ + ▶ リスト内包衚蚘 + +
+ [匏 for 倉数 in むテラブル] + ずいう圢でリストを1行で䜜る曞き方。 䟋[x*2 for x in range(3)] + → + [0, 2, 4]。 CPython の最適化呜什が䜿われるため、for + append() + より高速。 +
+
+ +
+ + ▶ + 早期リタヌンそうきりたヌん + +
+ 関数の先頭で特殊なケヌスを刀定し、すぐに + return + するこずで埌続の凊理をシンプルに保぀テクニック。 + 「ネストを深くしない」コヌドスタむルの䞀぀。 +
+
+ +
+ + ▶ bool は int + のサブクラス + +
+ Python では + True == 1、False == 0 + ずしお扱われる。 そのため + isinstance(True, int) + は + True + を返す。 型チェックでは + bool を先に匟くこずでこのバグを防げる。 +
+
+
+
+ +
+ LeetCode 118 — Pascal's Triangle | 行の積み䞊げ法 O(n²) +
+
+ + + + + + diff --git a/public/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html b/public/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html new file mode 100644 index 0000000..86c2048 --- /dev/null +++ b/public/Algorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html @@ -0,0 +1,2001 @@ + + + + + + LeetCode 118 — Pascal's Triangle + + + + + + + + + + + + + + + + +
+ + + + +
+

+ アルゎリズム抂芁 +

+ +
+

+ 💡 + この問題を䞀蚀で蚀うず「䞉角圢の圢に数倀を䞊べ、䞊から1行ず぀積み䞊げお完成させる問題」 +

+

+ 各行の倀は「真䞊の巊ず右の倀を足すだけ」で決たりたす。この「局所ルヌルの積み重ね」は + 動的蚈画法郚分問題の答えを再利甚しお党䜓を解く技法の最良な入門䟋です。 +

+
+ +
+

+ ⚠ なぜ単玔な方法では解けないのか +

+
    +
  • + 各行は前の行の倀がなければ蚈算できない。行をたたいだ䟝存関係がある。 +
  • +
  • + 党行を保持しお返す必芁があるため、出力サむズ自䜓が O(n²) + になる。これは避けられない䞋限。 +
  • +
  • + Python では + bool が + int + のサブクラスなので、型チェックの順番を誀るずバグになる詳现は FAQ + 参照。 +
  • +
+
+ +
+
+
O(n²)
+
時間蚈算量
+
+
+
O(n²)
+
空間蚈算量
+
+
+
+ 1 â‰€ n â‰€ 30 +
+
numRows の範囲
+
+
+
+ list[list[int]] +
+
戻り倀の型
+
+
+ +
+
+

+ 📥 入力 / 📀 出力の䟋 +

+
+
# 入力
+
numRows = 5
+
# 出力
+
[[1],
+
 [1, 1],
+
 [1, 2, 1],
+
 [1, 3, 3, 1],
+
 [1, 4, 6, 4, 1]]
+
+

+ ✅ なぜこれが正解か行2の + 2 は行1の + 1+1、 行3の + 3 は行2の + 1+2 および + 2+1。すべお定矩通り。 +

+
+
+

+ 📐 パスカルの䞉角圢のルヌル2぀だけ +

+
+
+ ルヌル 1 + 各行の䞡端は必ず 1 +
+
+ ルヌル 2 + 内偎の芁玠 = 真䞊の巊 + 真䞊の右
+ 䟋行2の 2 = + 行1の 1 + 1 +
+
+
+
+
+ + +
+

+ ステップバむステップ解説 +

+

+ numRows = 5 を䟋に、アルゎリズムの各ステップを远いたす。 +

+
+
+ + +
+

+ Python 実装 +

+ +
+

+ 📋 このコヌドの構造先に党䜓像を把握しよう +

+
    +
  1. 入力の怜蚌型チェックbool を先に匟くず範囲チェック1〜30
  2. +
  3. + 結果リスト + triangle + を空で初期化し、for + ルヌプで行を積み䞊げる +
  4. +
  5. + 各行は + _build_row() + ヘルパヌで構築行0・行1は固定倀を返す +
  6. +
  7. + 行2以降前行を参照し、リスト内包衚蚘で内偎を蚈算しお + [1]+inner+[1] + で完成 +
  8. +
+
+ +

+ ▾ 業務開発版型怜蚌・コメント付き +

+
from __future__ import annotations
+
+
+class Solution:
+    """LeetCode 118: Pascal's Triangle — 行の積み䞊げ法"""
+
+    def generate(self, numRows: int) -> list[list[int]]:
+        # ── 入力怜蚌型チェック ────────────────────────────────────
+        # Python では bool が int のサブクラスなので先に bool を匟く
+        if isinstance(numRows, bool) or not isinstance(numRows, int):
+            raise TypeError(f"numRows must be int, got: {type(numRows).__name__}")
+
+        # ── 入力怜蚌範囲チェック ──────────────────────────────────
+        if numRows < 1 or numRows > 30:
+            raise ValueError(f"numRows must be 1‒30, got: {numRows}")
+
+        # ── 結果栌玍甚リスト ──────────────────────────────────────────
+        triangle: list[list[int]] = []
+
+        # ── 行を 1 行ず぀積み䞊げる ───────────────────────────────────
+        for row_index in range(numRows):
+            current_row = self._build_row(triangle, row_index)
+            triangle.append(current_row)
+
+        return triangle
+
+    def _build_row(self, triangle: list[list[int]], row_index: int) -> list[int]:
+        # 基底条件1行0 は [1] 固定前行が存圚しないので早期リタヌン
+        if row_index == 0:
+            return [1]
+
+        # 基底条件2行1 は [1, 1] 固定内偎の芁玠が存圚しない
+        if row_index == 1:
+            return [1, 1]
+
+        # 行2以降前の行を参照しお内偎の芁玠をリスト内包衚蚘で蚈算
+        prev: list[int] = triangle[row_index - 1]
+
+        # CPython の LIST_APPEND 呜什が効くため、for+append より高速
+        inner: list[int] = [
+            prev[col - 1] + prev[col]   # 真䞊の巊 + 真䞊の右
+            for col in range(1, row_index)
+        ]
+
+        return [1] + inner + [1]
+
+ +
+

+ ▶ 入力䟋 numRows = 5 での動䜜トレヌス +

+
+入力: numRows = 5
+
+[怜蚌] isinstance(5, bool)→False, isinstance(5, int)→True, 1≀5≀30 ✅
+
+[row_index=0] _build_row([], 0)  → [1]             triangle=[[1]]
+[row_index=1] _build_row(.., 1)  → [1,1]            triangle=[[1],[1,1]]
+[row_index=2] prev=[1,1]
+              inner: col=1 → 1+1=2  →  inner=[2]
+              return [1]+[2]+[1] = [1,2,1]            triangle=[[1],[1,1],[1,2,1]]
+[row_index=3] prev=[1,2,1]
+              inner: col=1→1+2=3, col=2→2+1=3  →  inner=[3,3]
+              return [1,3,3,1]                        triangle=[..,[1,3,3,1]]
+[row_index=4] prev=[1,3,3,1]
+              inner: col=1→1+3=4, col=2→3+3=6, col=3→3+1=4  →  inner=[4,6,4]
+              return [1,4,6,4,1]                      triangle=[..,[1,4,6,4,1]]
+
+出力: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] ✅
+
+ +

+ ▾ 競技プログラミング版LeetCode 提出甚・最短実装 +

+
class Solution:
+    def generate(self, numRows: int) -> list[list[int]]:
+        tri: list[list[int]] = [[1]]
+        for i in range(1, numRows):
+            p = tri[-1]          # tri[-1] → 末尟行を O(1) で取埗Python の負むンデックス
+            tri.append([1] + [p[j-1] + p[j] for j in range(1, i)] + [1])
+        return tri
+
+
+ + +
+

+ 凊理フロヌチャヌト +

+ +
+

+ 🗺 フロヌチャヌトの読み方 +

+
+
+ + + + 楕円緑 開始・終了 +
+
+ + + + 四角青 凊理ステップ +
+
+ + + + ひし圢黄 条件分岐 +
+
+ はい + いいえ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + 開始 + + + + + + + + + 入力怜蚌 + + + (型・範囲チェック) + + + + + + TypeError / + + + ValueError + + + + + No + + + + + Yes + + + + + triangle = [] を初期化 + + + (結果を栌玍する 2 次元リスト) + + + + + + + + + row_index < numRows ? + + + (ルヌプ継続の刀定) + + + + + + triangle + + + を返す + + + + + No + + + + + Yes + + + + + _build_row() 呌び出し + + + (珟圚の行番号を枡す) + + + + + + + + + row_index ≀ 1 ? + + + (基底条件の刀定) + + + + + + [1] たたは + + + [1, 1] を返す + + + + + Yes + + + + + + + + No + + + + + prev = triangle[row_index − 1] + + + (前の行を参照する) + + + + + + + + + リスト内包衚蚘で inner を蚈算 + + + prev[c−1] + prev[c] の党おの c + + + + + + + + + row = [1] + inner + [1] + + + (䞡端に 1 を付けお行を完成) + + + + + + + + + triangle.append(row) + + + (完成した行を䞉角圢に远加) + + + + + + + + + row_index += 1 + + + (次の行ぞ進む) + + + + + 繰り返す + +
+ +
+

+ 🔎 入力䟋 numRows = 5 でのフロヌ远跡 +

+
    +
  1. + 「開始」→ 入力怜蚌isinstance + で型ず範囲を確認→ 怜蚌通過 +
  2. +
  3. + triangle = [] + を初期化。ルヌプに入る。 +
  4. +
  5. + row_index=0: ルヌプ条件 0<5 → Yes → + _build_row + → row_index≀1 → Yes → + [1] を + append。 +
  6. +
  7. + row_index=1: 同様に + [1,1] を + append。 +
  8. +
  9. + row_index=2〜4: row_index≀1 → No → prev 参照 → inner 蚈算 → + [1]+inner+[1] + → append → row_index++。 +
  10. +
  11. + row_index=5: ルヌプ条件 5<5 → No → + triangle + を返す。 +
  12. +
+
+
+ + +
+

+ 蚈算量分析 +

+ +
+

+ 📖 Big-O 蚘法の読み方入力 n + が倧きくなるに぀れ凊理時間がどう倉わるかの目安 +

+
+
+
O(1)
+
+ 垞に䞀定
䟋蟞曞の盎接匕き +
+
+
+
O(n)
+
+ 入力に比䟋
䟋リストを1回走査 +
+
+
+
O(n log n)
+
+ n より少し倚い
䟋゜ヌトアルゎリズム +
+
+
+
O(n²)
+
+ 入力の2乗
䟋二重ルヌプ総圓たり +
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ 皮類 + + 蚈算量 + + 理由 +
+ 時間蚈算量 + + O(n²) + + 党芁玠数 = 1+2+
+n = n(n+1)/2。各芁玠を1床だけ蚈算する。 +
+ 空間蚈算量 + + O(n²) + + 党行を + triangle + に保持しお返すため。 +
+ 1行あたり + + O(k) + + k 行目の構築は k 個の芁玠を蚈算するだけk は行むンデックス。 +
+
+ +
+

+ 🔍 なぜ O(n²) になるのか、そしお䞋回れないのか +

+

+ 行 k の芁玠数は k+1 個なので、党芁玠数は 1+2+3+
+n = n(n+1)/2 ≈ n²/2 + です。これは Big-O 衚蚘で O(n²) になりたす。 + 重芁なのは「出力自䜓が n²/2 + 個の芁玠を持぀」ずいう点です。どんなに賢いアルゎリズムを䜿っおも、 + 出力を生成するだけで O(n²) の時間が必芁になりたす。この O(n²) + は䞋限どうしおも䞋回れないコストであり、 + 本実装はその䞋限を達成しおいたす。 +

+
+ +
+

+ 📊 numRows ごずの芁玠数の増え方 +

+ + + + + + + + + + + + + + + + + + + + + +
+ numRows (n) + 15102030
+ 党芁玠数 + + 1 + + 15 + + 55 + + 210 + + 465 +
+
+
+ + +
+

+ 📖 甚語集 +

+

+ このペヌゞで登堎した専門甚語をたずめたした。分からない蚀葉が出おきたずきに参照しおください。五十音順 +

+
+
+ + ▶ むテラブル + +
+ for + ルヌプで繰り返せるオブゞェクトの総称。 リスト・タプル・range() + など。 䟋range(1, 3) + は + 1, 2 + を順に返すむテラブル。 +
+
+ +
+ + ▶ むテレヌション + +
+ ルヌプの1回分の繰り返し凊理のこず。for i in range(5) + は5回むテレヌションする。 +
+
+ +
+ + ▶ 䞋限かげん + +
+ どんなアルゎリズムを䜿っおも越えられない蚈算量の最䜎ラむン。 + この問題では出力自䜓が O(n²) 個の芁玠を持぀ため、O(n²) が䞋限になる。 +
+
+ +
+ + ▶ + 基底条件きおいじょうけん + +
+ 再垰やルヌプの終了条件、たたは特殊ケヌスを凊理する最初の条件。 + この問題では行0[1]ず行1[1,1]が基底条件。 + 内偎の芁玠が存圚しないため、汎甚ロゞックずは別に凊理する。 +
+
+ +
+ + ▶ + 空間蚈算量くうかんけいさんりょう + +
+ 凊理䞭に䜿うメモリ量が入力 n に察しおどう倉化するかの目安。 + 蟞曞に䟋えるず「探偵がメモを取るためのノヌトの枚数」。 + この問題では党行を保存するため O(n²)。 +
+
+ +
+ + ▶ + 時間蚈算量じかんけいさんりょう + +
+ 入力の倧きさ n に察しお凊理にかかる手間がどう増えるかの目安。 「n + が2倍になったら凊理時間は䜕倍か」を衚す Big-O 蚘法で衚珟する。 O(n²) + は「n が2倍になるず凊理は4倍になる」ずいう意味。 +
+
+ +
+ + ▶ + 動的蚈画法どうおきけいかくほう + +
+ 問題を小さな郚分問題に分割し、その結果を再利甚しながら党䜓の答えを組み立おる手法。 + 料理に䟋えるず「昚日䜜ったスヌプのだしを今日の料理に䜿い回す」むメヌゞ。 + この問題では「前の行郚分問題の答えを䜿っお次の行を䜜る」のが動的蚈画法に圓たる。 +
+
+ +
+ + ▶ + 䞍倉条件ふぞんじょうけん + +
+ アルゎリズムが正しく動くために、ルヌプ䞭ずっず成り立ち続けるべき条件ルヌプ䞍倉条件ずも蚀う。 + この問題では「ルヌプ開始時に + triangle + には正しいパスカルの行が入っおいる」が䞍倉条件。 +
+
+ +
+ + ▶ バむトコヌド + +
+ Python の゜ヌスコヌドが実行前に倉換される䞭間圢匏。 CPython + はリスト内包衚蚘を + LIST_APPEND + ずいう専甚の最適化呜什にコンパむルするため、 通垞の + for + append() + より高速に動䜜する。 +
+
+ +
+ + ▶ リスト内包衚蚘 + +
+ [匏 for 倉数 in むテラブル] + ずいう圢でリストを1行で䜜る曞き方。 䟋[x*2 for x in range(3)] + → + [0, 2, 4]。 CPython の最適化呜什が䜿われるため、for + append() + より高速。 +
+
+ +
+ + ▶ + 早期リタヌンそうきりたヌん + +
+ 関数の先頭で特殊なケヌスを刀定し、すぐに + return + するこずで埌続の凊理をシンプルに保぀テクニック。 + 「ネストを深くしない」コヌドスタむルの䞀぀。 +
+
+ +
+ + ▶ bool は int + のサブクラス + +
+ Python では + True == 1、False == 0 + ずしお扱われる。 そのため + isinstance(True, int) + は + True + を返す。 型チェックでは + bool を先に匟くこずでこのバグを防げる。 +
+
+
+
+ +
+ LeetCode 118 — Pascal's Triangle | 行の積み䞊げ法 O(n²) +
+
+ + + + + + diff --git a/public/index.html b/public/index.html index d970233..4b05395 100644 --- a/public/index.html +++ b/public/index.html @@ -416,7 +416,7 @@

🧪 Algorithm Study Index

-

177 interactive lessons across 6 domains

+

178 interactive lessons across 6 domains

@@ -431,9 +431,9 @@

- + @@ -476,6 +476,7 @@

  • 🧩LeetCode 110 · Balanced Binary TreeAlgorithm/BinaryTree/leetcode/110. Balanced Binary Tree/claude sonnet 4.6 adaptive/README_react.html
  • 🧩LeetCode 111 - Minimum Depth of Binary Tree | BFS解説Algorithm/BinaryTree/leetcode/111. Minimum Depth of Binary Tree/claude sonnet 4.6 adaptive/README_react.html
  • 🧩LeetCode 112 – Path Sum | 再垰DFS解説Algorithm/BinaryTree/leetcode/112. Path Sum/claude sonnet 4.6 adaptive/README_react.html
  • +
  • 🧩LeetCode 118 — Pascal's TriangleAlgorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html
  • 🧩LeetCode 5: Longest Palindromic Substring - 䞭心展開法Algorithm/ExpandAroundCenter/leetcode/5. Longest Palindromic Substring/Claude/README.html
  • 🧩LeetCode 66: Plus One - 右から巊ぞの繰り䞊がり凊理Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/README_react.html
  • 🧩LeetCode 67: Add Binary - 二進数加算Algorithm/TwoPointers/leetcode/67. Add Binary/Claude/README_react.html
  • @@ -509,8 +510,8 @@

  • 🧩Search in Rotated Sorted Array II - Technical AnalysisAlgorithm/BinarySearch/leetcode/81. Search in Rotated Sorted Array II/Claude/README.html
  • 🧩Set Matrix Zeroes Algorithm - Python ImplementationAlgorithm/Other/leetcode/73. Set Matrix Zeroes/Claude/README.html
  • 🧩Sort Colors Algorithm - Interactive Technical GuideAlgorithm/Dutch National Flag/leetcode/75. Sort Colors/Claude/README.html
  • -
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/54. Spiral Matrix/Claude/README.html
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/59. Spiral Matrix II/Claude/README.html
  • +
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/54. Spiral Matrix/Claude/README.html
  • 🧩Subsets II - 反埩的拡匵法による重耇排陀 | アルゎリズム解説Algorithm/Other/leetcode/90. Subsets II/Claude/README.html
  • 🧩Two-Pointer Algorithm: Remove Duplicates from Sorted Array IIAlgorithm/TwoPointers/leetcode/80. Remove Duplicates from Sorted Array II/Claude/README.html
  • 🧩TypeScript Binary Search Performance AnalysisAlgorithm/BinarySearch/leetcode/34. Find First and Last Position of Element in Sorted Array/READEME-typescript.html
  • @@ -660,6 +661,7 @@

  • 🧩LeetCode 110 · Balanced Binary TreeAlgorithm/BinaryTree/leetcode/110. Balanced Binary Tree/claude sonnet 4.6 adaptive/README_react.html
  • 🧩LeetCode 111 - Minimum Depth of Binary Tree | BFS解説Algorithm/BinaryTree/leetcode/111. Minimum Depth of Binary Tree/claude sonnet 4.6 adaptive/README_react.html
  • 🧩LeetCode 112 – Path Sum | 再垰DFS解説Algorithm/BinaryTree/leetcode/112. Path Sum/claude sonnet 4.6 adaptive/README_react.html
  • +
  • 🧩LeetCode 118 — Pascal's TriangleAlgorithm/Other/leetcode/118. Pascal's Triangle/claude sonnet 4.6 adaptive/README_React.html
  • 🧩LeetCode 5: Longest Palindromic Substring - 䞭心展開法Algorithm/ExpandAroundCenter/leetcode/5. Longest Palindromic Substring/Claude/README.html
  • 🧩LeetCode 66: Plus One - 右から巊ぞの繰り䞊がり凊理Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/README_react.html
  • 🧩LeetCode 67: Add Binary - 二進数加算Algorithm/TwoPointers/leetcode/67. Add Binary/Claude/README_react.html
  • @@ -693,8 +695,8 @@

  • 🧩Search in Rotated Sorted Array II - Technical AnalysisAlgorithm/BinarySearch/leetcode/81. Search in Rotated Sorted Array II/Claude/README.html
  • 🧩Set Matrix Zeroes Algorithm - Python ImplementationAlgorithm/Other/leetcode/73. Set Matrix Zeroes/Claude/README.html
  • 🧩Sort Colors Algorithm - Interactive Technical GuideAlgorithm/Dutch National Flag/leetcode/75. Sort Colors/Claude/README.html
  • -
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/54. Spiral Matrix/Claude/README.html
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/59. Spiral Matrix II/Claude/README.html
  • +
  • 🧩Spiral Matrix Algorithm AnalysisAlgorithm/Other/leetcode/54. Spiral Matrix/Claude/README.html
  • 🧩Subsets II - 反埩的拡匵法による重耇排陀 | アルゎリズム解説Algorithm/Other/leetcode/90. Subsets II/Claude/README.html
  • 🧩Two-Pointer Algorithm: Remove Duplicates from Sorted Array IIAlgorithm/TwoPointers/leetcode/80. Remove Duplicates from Sorted Array II/Claude/README.html
  • 🧩TypeScript Binary Search Performance AnalysisAlgorithm/BinarySearch/leetcode/34. Find First and Last Position of Element in Sorted Array/READEME-typescript.html
  • @@ -837,7 +839,7 @@

    🧪 - Generated on 2026-05-12 + Generated on 2026-05-13