From 3707743459971c730119ae16f3036b0bb2e88223 Mon Sep 17 00:00:00 2001 From: myoshizumi Date: Sun, 16 Nov 2025 18:24:59 +0900 Subject: [PATCH] Math: leetcode Palindrome Number --- .../claud sonnet 4.5/README.md | 295 ++++ .../claud sonnet 4.5/README_react.html | 1326 +++++++++++++++++ .../PalindromeNumber_js.ipynb | 373 +++++ .../PalindromeNumber_py.ipynb | 422 ++++++ .../PalindromeNumber_ts.ipynb | 368 +++++ .../gpt 5.1 thinking customized/README.md | 379 +++++ README.md | 762 +++++----- 7 files changed, 3549 insertions(+), 376 deletions(-) create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README.md create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README_react.html create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_js.ipynb create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_py.ipynb create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_ts.ipynb create mode 100644 Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/README.md diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README.md b/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README.md new file mode 100644 index 00000000..9f688cbc --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README.md @@ -0,0 +1,295 @@ +# Palindrome Number - 数値のまま回文判定 + +

目次

+ +- [概要](#overview) +- [アルゴリズム要点(TL;DR)](#tldr) +- [図解](#figures) +- [正しさのスケッチ](#correctness) +- [計算量](#complexity) +- [Python実装](#impl) +- [CPython最適化ポイント](#cpython) +- [エッジケースと検証観点](#edgecases) +- [FAQ](#faq) + +--- + +

概要

+ +**問題**: 整数 `x` が 10 進表記で回文(左右対称)かどうかを判定する。 + +**要件**: + +- 負数は必ず `False`(先頭に `-` が付くため対称にならない) +- `0` 以外で末尾が `0` の数は `False`(例: `10` → `"01"` とは読めない) +- Follow up: **文字列変換なし**で解く +- 制約: `-2^31 <= x <= 2^31 - 1` + +**正当性**: 右半分だけを数値のまま反転し、左半分と比較することで回文性を判定。 + +**安定性**: 追加メモリ `O(1)` で、整数演算のみを使用。 + +--- + +

アルゴリズム要点(TL;DR)

+ +- **戦略**: 数値を文字列に変換せず、右半分だけを反転して左半分と比較 +- **データ構造**: 整数変数 2 つ(`x` と `reverted`)のみ +- **計算量**: 時間 `O(d)`(d = 桁数)、空間 `O(1)` +- **メモリ**: 定数個の整数のみ使用。リスト・文字列などの追加データ構造は不要 + +**核心ロジック**: + +1. 負数と末尾 0(0 自身を除く)を早期 return で弾く +2. `x` の末尾から 1 桁ずつ取り出して `reverted` に積み上げる +3. `x <= reverted` になったら終了 +4. 偶数桁: `x == reverted`、奇数桁: `x == reverted // 10` なら回文 + +--- + +

図解

+ +## フローチャート + +```mermaid +flowchart TD + Start[Start solve] --> Neg{x < 0} + Neg -- Yes --> RetF[Return False] + Neg -- No --> Trail{x % 10 == 0 and x != 0} + Trail -- Yes --> RetF + Trail -- No --> Single{x < 10} + Single -- Yes --> RetT[Return True] + Single -- No --> Init[rev = 0] + Init --> Loop{x > rev} + Loop -- No --> Check{x == rev or x == rev // 10} + Loop -- Yes --> Extract[digit = x % 10] + Extract --> Update[rev = rev * 10 + digit] + Update --> Divide[x = x // 10] + Divide --> Loop + Check -- Yes --> RetT + Check -- No --> RetF +``` + +**説明**: 負数・末尾 0 を早期判定した後、1 桁数は即座に True を返す。それ以外は右半分を反転しながら `x` を縮小し、`x <= rev` になった時点で偶数桁・奇数桁の判定を行う。 + +### データフロー図 + +```mermaid +graph LR + subgraph Input_Check + A[Input x] --> B[Negative check] + B --> C[Trailing zero check] + C --> D[Single digit check] + end + subgraph Revert_Loop + D --> E[Initialize rev = 0] + E --> F[Extract digit from x] + F --> G[Build rev = rev * 10 + digit] + G --> H[Shrink x = x // 10] + H --> I{x > rev} + I -- Yes --> F + I -- No --> J[Compare x with rev] + end + J --> K[Output boolean] +``` + +**説明**: 入力をまず 3 段階でフィルタリング(負数・末尾 0・1 桁数)し、その後ループで右半分を反転。最後に左半分と比較して結果を返す。 + +--- + +

正しさのスケッチ

+ +**不変条件**: + +- ループ中、`rev` には常に「まだ見ていない x の右側の桁を反転したもの」が格納される +- `x` は毎回末尾 1 桁を削除され、左側の桁だけが残る + +**網羅性**: + +- 負数: 必ず False(先頭に `-` が付く) +- 末尾 0(0 自身を除く): 必ず False(先頭に 0 は来ない) +- 1 桁数(0 〜 9): すべて回文 +- 2 桁以上: ループで右半分と左半分を分離して比較 + +**基底条件**: + +- `x < 10` の場合、ループに入る前に True を返す +- ループは `x <= rev` で終了(右半分が左半分以上の桁数になった時点) + +**終了性**: + +- 毎回 `x //= 10` で桁数が減るため、有限回で `x <= rev` が成立 + +--- + +

計算量

+ +| 項目 | 計算量 | 説明 | +| -------- | ------ | -------------------------------------------------------- | +| **時間** | `O(d)` | d は x の桁数(≒ log₁₀( \| x \| ))。ループは高々 d/2 回 | +| **空間** | `O(1)` | 追加メモリは `rev`, `digit` など定数個の整数のみ | + +**in-place vs Pure 比較**: + +- この問題は入力を直接書き換えないため、本質的には Pure +- ローカル変数 `x` をコピーとして扱い、元の引数は不変 + +--- + +

Python実装

+ +```python +from __future__ import annotations + + +class Solution: + """ + Palindrome Number 判定クラス(競技プログラミング向け最小構成) + + LeetCode が呼び出すのは isPalindrome(x) のみ。 + """ + + def isPalindrome(self, x: int) -> bool: + """ + 整数 x が 10 進表記で回文かどうかを判定する。 + + Args: + x: 判定対象の整数(32bit 符号付き整数) + + Returns: + x が 10 進表記で回文であれば True、そうでなければ False。 + + Time Complexity: + O(d) (d は x の桁数 ≒ log10(|x|)) + + Space Complexity: + O(1) 追加メモリは定数個の整数のみ。 + """ + # 負数、0 以外で末尾が 0 の数は回文にならない + if x < 0 or (x % 10 == 0 and x != 0): + return False + + # 0〜9 は 1 桁なので必ず回文 + if x < 10: + return True + + rev: int = 0 + + # 右半分を反転しつつ、左半分と比較できる状態まで進める + # ループを抜ける条件: + # - 偶数桁: x と rev が同じ桁数になった時点で x <= rev + # - 奇数桁: 中央 1 桁を含んだ rev の方が 1 桁多くなった時点で x < rev + while x > rev: + digit: int = x % 10 # 末尾 1 桁を取得 + rev = rev * 10 + digit # rev に桁を追加 + x //= 10 # 整数除算で末尾 1 桁を削除 + + # 偶数桁: x == rev + # 奇数桁: 中央 1 桁を無視するため、rev // 10 と比較 + return x == rev or x == rev // 10 +``` + +**主要ステップ**: + +1. **早期リターン**: 負数と末尾 0(0 自身を除く)を弾く +2. **1 桁数の特別処理**: 0〜9 は必ず True +3. **反転ループ**: `x > rev` の間、`x` の末尾を `rev` に追加し、`x` を縮小 +4. **最終比較**: 偶数桁と奇数桁の両方に対応した判定 + +--- + +

CPython最適化ポイント

+ +1. **整数演算のみ使用**: + - `//` と `%` は C レベルで実装されており、Python の文字列操作より高速 + - `str()` やスライスを使わないことで、オブジェクト生成コストを回避 + +2. **ローカル変数のみ**: + - ループ内は `x`, `rev`, `digit` のみで完結 + - 属性アクセス(`self.x` など)や関数呼び出しを排除 + +3. **早期リターン**: + - 負数・末尾 0・1 桁数を事前に弾くことで、不要なループを回避 + +4. **追加データ構造なし**: + - `list`, `deque`, `dict` などを使わないため、GC 負荷がゼロ + - メモリアロケーションも最小限 + +5. **計測値のブレ**: + - LeetCode の Runtime は環境ノイズが大きい(6ms〜10ms 程度は普通にブレる) + - 同じコードでも再提出で順位が変わることがあるため、51% という数字はあくまで参考値 + +**文字列版との比較**: + +- `str(x)` + スライス反転の方が実測で速いケースもある(C 実装のため定数倍が小さい) +- ただし Follow up(文字列変換なし)を満たすなら、数値版が正統派 + +--- + +

エッジケースと検証観点

+ +| ケース | 入力例 | 期待出力 | 備考 | +| ---------------- | ----------------------- | -------- | ----------------------------------- | +| **0 単体** | `x = 0` | True | 1 桁数なので回文 | +| **1 桁数** | `x = 5`, `9` | True | すべて回文 | +| **負数** | `x = -121`, `-1` | False | 先頭に `-` が付くため対称にならない | +| **末尾 0** | `x = 10`, `100` | False | 先頭に 0 は来ないため回文ではない | +| **2 桁回文** | `x = 11`, `22` | True | 偶数桁の典型例 | +| **2 桁非回文** | `x = 12`, `10` | False | 左右が異なる | +| **奇数桁回文** | `x = 121`, `12321` | True | 中央 1 桁を無視した比較 | +| **偶数桁回文** | `x = 1221`, `123321` | True | 左右が完全に一致 | +| **奇数桁非回文** | `x = 123`, `12345` | False | 中央を無視しても一致しない | +| **制約上限** | `x = 2147483647` | False | 32bit 最大値(回文ではない) | +| **制約下限** | `x = -2147483648` | False | 32bit 最小値(負数) | +| **大きな回文** | `x = 1000000001` (10桁) | True | 桁数が多くても正しく判定 | +| **末尾複数の 0** | `x = 1000` | False | 0 以外で末尾が 0 なら False | + +**検証時の注意**: + +- 型安全性: LeetCode は入力を保証するが、業務用では `isinstance(x, int)` チェックが必要 +- オーバーフロー: Python の `int` は任意精度なので心配不要(他言語では注意が必要) + +--- + +

FAQ

+ +**Q1. なぜ文字列変換を使わないのか?** + +- Follow up で「文字列変換なしで解けるか?」と問われているため +- 数値版の方が空間計算量 `O(1)` を達成でき、理論的にも優れている + +**Q2. 偶数桁と奇数桁で処理が違うのはなぜ?** + +- 奇数桁の場合、中央の 1 桁はどちらの半分にも属さない +- 例: `121` → `x = 1`, `rev = 12` となった時点で、`1 == 12 // 10` で判定 + +**Q3. `x <= rev` で終了する理由は?** + +- 右半分を反転しながら `x` を縮小すると、ちょうど半分の桁数に達した時点で `x <= rev` が成立 +- これ以上進めると、左半分が足りなくなるため停止 + +**Q4. LeetCode で 51% という順位は悪いのか?** + +- Python の実行環境は計測ノイズが大きく、同じコードでも 6ms〜10ms でブレる +- アルゴリズム的には最適なので、51% は十分良好な結果 + +**Q5. 業務開発で使う場合の注意点は?** + +- 型チェック(`isinstance(x, int)`)を追加 +- 値域チェック(32bit 整数の範囲内か)を追加 +- エラーハンドリング(`TypeError`, `ValueError`)を実装 + +**Q6. より高速化する方法は?** + +- LeetCode 用にクラス・docstring を最小化(定数倍の改善) +- 文字列版(`str(x)[::-1]`)も実測で速いケースがある(ただし Follow up 不満足) + +**Q7. なぜ `rev` を `reverted` と書かないのか?** + +- 競技プログラミングでは変数名を短くするのが一般的(タイプ数削減) +- 業務開発では `reverted_half` など明示的な名前が推奨される + +**Q8. `x //= 10` と `x = x // 10` の違いは?** + +- 両者は同じ(代入演算子の短縮形) +- CPython では最適化されるため、パフォーマンス差はほぼゼロ diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README_react.html b/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README_react.html new file mode 100644 index 00000000..eafdc7b2 --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/claud sonnet 4.5/README_react.html @@ -0,0 +1,1326 @@ + + + + + + LeetCode 9: Palindrome Number - 数値反転による回文判定 + + + + + + + + + + + + + + + + + +
+ + + + +
+

+ アルゴリズム概要 +

+ +

+ 整数 + x + が 10 進表記で回文(左右対称)かどうかを判定します。 +

+ +
+

入出力例

+
例1: x = 121  → true  (121は左右対称)
+例2: x = -121 → false (負数は先頭に-が付く)
+例3: x = 10   → false (01とは読めない)
+
+ +
+

制約条件

+
    +
  • + -2³¹ ≤ x ≤ 2³¹ - 1 +
  • +
  • Follow up: 文字列変換なしで解けるか?
  • +
+
+ +
+

戦略

+
    +
  • 早期リターン: 負数と末尾0(0自身を除く)を先に弾く
  • +
  • + 半分反転: 右半分だけを数値のまま反転し、左半分と比較 +
  • +
  • 偶数/奇数桁対応: 中央の1桁を考慮した判定
  • +
  • 時間 O(d): d = 桁数 ≒ log₁₀(|x|)
  • +
  • 空間 O(1): 定数個の整数変数のみ使用
  • +
+
+
+ + +
+

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

+
+
+ + +
+

+ Python実装 +

+
class Solution:
+    def isPalindrome(self, x: int) -> bool:
+        """
+        整数 x が 10 進表記で回文かどうかを判定する。
+
+        Args:
+            x: 判定対象の整数(32bit 符号付き整数)
+
+        Returns:
+            x が 10 進表記で回文であれば True、そうでなければ False。
+
+        Time Complexity: O(d)  (d は x の桁数 ≒ log10(|x|))
+        Space Complexity: O(1)  追加メモリは定数個の整数のみ。
+        """
+        # 負数、0 以外で末尾が 0 の数は回文にならない
+        if x < 0 or (x % 10 == 0 and x != 0):
+            return False
+
+        # 0〜9 は 1 桁なので必ず回文
+        if x < 10:
+            return True
+
+        rev: int = 0
+
+        # 右半分を反転しつつ、左半分と比較できる状態まで進める
+        # ループを抜ける条件:
+        #   - 偶数桁: x と rev が同じ桁数になった時点で x <= rev
+        #   - 奇数桁: 中央 1 桁を含んだ rev の方が 1 桁多くなった時点で x < rev
+        while x > rev:
+            digit: int = x % 10  # 末尾 1 桁を取得
+            rev = rev * 10 + digit  # rev に桁を追加
+            x //= 10  # 整数除算で末尾 1 桁を削除
+
+        # 偶数桁: x == rev
+        # 奇数桁: 中央 1 桁を無視するため、rev // 10 と比較
+        return x == rev or x == rev // 10
+
+ + +
+

+ フローチャート +

+
+ + + + + + + + + + + + + + + + + + + + 開始 + + + + + + + + + x < 0? + 負数判定 + + + + + + はい + + + + + Return + False + + + + + + いいえ + + + + + + x % 10 == 0 + and x != 0? + 末尾0判定 + + + + + + はい + + + + + + いいえ + + + + + + x < 10? + 1桁数判定 + + + + + + はい + + + + + Return + True + + + + + + いいえ + + + + + + 初期化 + rev = 0 + + + + + + + + + x > rev? + ループ継続 + + + + + + はい + + + + + + digit取得 + x % 10 + + + + + + + + + rev更新 + rev*10 + digit + + + + + + + + + x縮小 + x //= 10 + + + + + + 次の反復へ + + + + + + いいえ + + + + + + x == rev + or rev//10? + + + + + + はい + + + + + + いいえ + + +
+ +

+ フローの説明:
+ 1. 基底条件で負数・末尾0・1桁数を早期判定
+ 2. rev = 0 で初期化し、ループに入る
+ 3. x > rev の間、右側の桁を反転して rev に積み上げる
+ 4. 同時に x を縮小し、x <= rev になったらループ終了
+ 5. 最後に x == rev または x == rev // 10 で回文判定
+ 6. 左側の紫色の矢印でループバックし、次の反復へ進む +

+
+ + +
+

+ 計算量分析 +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ 項目 + + 本実装(数値反転) + + 代替案(文字列変換) +
+ 時間計算量 + + O(d) + + O(d) +
+ 空間計算量 + + O(1) + + O(d) + (文字列生成) +
+ Follow up対応 + + ✓ 満たす + + ✗ 満たさない +
+ 実装コスト + + 中(ループロジック) + + 低(str()+スライス) +
+
+ +
+

補足

+
    +
  • d は桁数(≒ log₁₀(|x|))
  • +
  • 数値反転版はメモリ効率が優れており、追加データ構造を使わない
  • +
  • 文字列版は実装が簡単だが、Follow upの要件を満たさない
  • +
  • LeetCode環境では実行時間にノイズがあり、両者の実測差は小さい
  • +
+
+
+
+ + + + + + + + + + + + + + + + + diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_js.ipynb b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_js.ipynb new file mode 100644 index 00000000..cea31533 --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_js.ipynb @@ -0,0 +1,373 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d9092b3b", + "metadata": {}, + "source": [ + "# 1. 問題の分析\n", + "\n", + "---\n", + "\n", + "### 競技プログラミング視点での分析\n", + "\n", + "* 入力: 32bit 符号付き整数 `x`(`-2^31 <= x <= 2^31 - 1`)\n", + "* 出力: `x` が「10進表記で左右対称かどうか」を示す真偽値\n", + "* 制約は非常にゆるいので、`O(log10 x)` 程度なら十分高速\n", + "* 素直な解:\n", + "\n", + " * 文字列に変換して両端から比較(実装容易)\n", + "* Follow up:\n", + "\n", + " * 文字列変換なしで判定\n", + " * 数値のまま桁を扱うロジックが必要\n", + "\n", + "### 業務開発視点での分析\n", + "\n", + "* 要件は「ただの真偽値判定」なので、例外は基本的に不要だが、今回はテンプレ要件に従い:\n", + "\n", + " * 型チェック(number / 整数 / finite)\n", + " * 値域チェック(32bit 符号付き整数)\n", + " * 想定外入力には `TypeError` / `RangeError`\n", + "* 本番コードとしては:\n", + "\n", + " * 数値ロジックは関数を小さくまとめ、変数名も意図がわかりやすいものにする\n", + " * ただし LeetCode 回答形式の制約上、1関数に収めるほうが実務より優先\n", + "\n", + "### JavaScript特有の考慮点\n", + "\n", + "* `Number` は 53bit 精度なので 32bit 整数は安全に扱える\n", + "* V8 最適化のため:\n", + "\n", + " * 単純な `for` / `while` ループ\n", + " * 一度決めた変数に異なる型を入れない(`reverted` は常に number)\n", + " * 余計なオブジェクト / 配列生成をしない(今回は数個の number だけ)\n", + "* GC 負荷はほぼゼロに等しいレベルの軽さ\n", + "\n", + "---\n", + "\n", + "## 2. アルゴリズムアプローチ比較\n", + "\n", + "---\n", + "\n", + "ここでは代表的に 3 パターンを比較します。\n", + "\n", + "| アプローチ | 内容概要 | 時間計算量 | 空間計算量 | JS実装コスト | 可読性 | 備考 |\n", + "| ----- | ------------- | ----- | ----- | ------- | --- | ---------------------------------------- |\n", + "| 方法A | 文字列化 + 両端比較 | O(d) | O(d) | 低 | 高 | `x.toString()` で簡単実装。Follow up ではNG |\n", + "| 方法B | 数値を**半分のみ**反転 | O(d) | O(1) | 中 | 中 | 文字列不使用。`while (x > reverted)` で半分だけ作る定石解 |\n", + "| 方法C | 数値全体を反転して比較 | O(d) | O(1) | 中 | 中 | オーバーフロー考慮が必要になるケースもあり注意(本問題では32bit制約あり) |\n", + "\n", + "※ `d` は桁数(`O(log10 x)` に相当)\n", + "\n", + "---\n", + "\n", + "## 3. 選択したアルゴリズムと理由\n", + "\n", + "---\n", + "\n", + "* 選択したアプローチ: **方法B: 数値を半分だけ反転する手法(文字列不使用)**\n", + "\n", + "### 理由\n", + "\n", + "* Follow up の要件「文字列にしない」を満たす\n", + "* 計算量は `O(d)`、追加メモリは定数 `O(1)` と最適クラス\n", + "* オーバーフローの心配が実質ない(反転も 32bit 整数内で完結)\n", + "* 判定ロジックがシンプル:\n", + "\n", + " * 負数は即 `false`\n", + " * 末尾が 0 で 0 でない数も即 `false`(`10, 20, ...` は回文でない)\n", + " * ループで「右半分を反転した値」と「左半分」を比較\n", + "\n", + "### アルゴリズム概要(方法B)\n", + "\n", + "1. `x < 0` → 回文にならないので `false`\n", + "2. `x % 10 === 0 && x !== 0` → 末尾0で先頭0にならないので `false`\n", + "3. `reverted = 0` として、右側の桁を順に `reverted` に取り込む\n", + "\n", + " * `while (x > reverted)`:\n", + "\n", + " * `reverted = reverted * 10 + (x % 10)`\n", + " * `x = Math.trunc(x / 10)`\n", + "4. ループ終了時には\n", + "\n", + " * 桁数が偶数: `x === reverted`\n", + " * 桁数が奇数: 真ん中 1 桁を捨てて `x === Math.trunc(reverted / 10)`\n", + "5. 上記いずれかを満たせば回文\n", + "\n", + "### JavaScript特有の最適化ポイント\n", + "\n", + "* `Math.trunc(x / 10)` を使用(`/` と `|0` 混在より一貫性が高く、型も Number のまま)\n", + "* `while` ループと単純な `number` 変数のみを使用\n", + "* 例外系(型チェック / 範囲チェック)は関数冒頭のコールドパスにまとめておき、ホットパスから分離\n", + "\n", + "---\n", + "\n", + "## 4. コード実装(solution.js)\n", + "\n", + "---\n", + "\n", + "* 実行環境: Node.js v22.14.0(CommonJS 想定)\n", + "* LeetCode 用シグネチャ準拠 + `module.exports` でローカル実行も可能にしています\n", + "\n", + "```javascript\n", + "'use strict';\n", + "\n", + "/**\n", + " * 判定対象の整数が 10 進表記で回文かどうかを返す。\n", + " *\n", + " * Constraints: -2^31 <= x <= 2^31 - 1\n", + " *\n", + " * Time Complexity: O(d) (d は x の桁数 ≒ log10(|x|))\n", + " * Space Complexity: O(1)\n", + " *\n", + " * @param {number} x - 判定対象の 32bit 符号付き整数\n", + " * @returns {boolean} 回文であれば true, そうでなければ false\n", + " * @throws {TypeError} 引数が number 型でない / 整数でない / 非有限値\n", + " * @throws {RangeError} 32bit 符号付き整数の範囲外\n", + " */\n", + "var isPalindrome = function (x) {\n", + " // ---- 入力検証(競技環境では通らない入力は来ないが、テンプレ要件に従い実装) ----\n", + " if (typeof x !== 'number' || !Number.isFinite(x)) {\n", + " throw new TypeError('Input must be a finite number');\n", + " }\n", + " if (!Number.isInteger(x)) {\n", + " throw new TypeError('Input must be an integer');\n", + " }\n", + "\n", + " // 32bit 符号付き整数範囲チェック\n", + " // -2^31 <= x <= 2^31 - 1\n", + " var INT_MIN = -2147483648; // -2 ** 31\n", + " var INT_MAX = 2147483647; // 2 ** 31 - 1\n", + " if (x < INT_MIN || x > INT_MAX) {\n", + " throw new RangeError('Input is out of 32-bit signed integer range');\n", + " }\n", + "\n", + " // ---- 本処理(数値のみで回文判定:Follow up 解法) ----\n", + "\n", + " // 負数は先頭に '-' が付くので回文にはならない\n", + " if (x < 0) return false;\n", + "\n", + " // 0 以外で末尾が 0 の数も回文にならない(先頭が 0 になりえないため)\n", + " if (x !== 0 && x % 10 === 0) return false;\n", + "\n", + " // revertedHalf: 右側半分を反転して作られる数\n", + " var revertedHalf = 0;\n", + " var original = x;\n", + "\n", + " // x が revertedHalf 以下になったら、半分以上の桁を処理したことになる\n", + " while (original > revertedHalf) {\n", + " // 末尾の桁を取り出す\n", + " var digit = original % 10;\n", + " // 反転側の末尾に桁を追加\n", + " revertedHalf = revertedHalf * 10 + digit;\n", + " // 左側の残り(末尾桁を捨てる)\n", + " original = Math.trunc(original / 10);\n", + " }\n", + "\n", + " // 桁数が偶数: 例) 1221 → original=12, revertedHalf=12\n", + " // 桁数が奇数: 例) 12321 → original=12, revertedHalf=123\n", + " // 真ん中の 3 は無視して比較する(revertedHalf / 10)\n", + " return original === revertedHalf || original === Math.trunc(revertedHalf / 10);\n", + "};\n", + "\n", + "// CommonJS export for local execution / tests (LeetCode 側では無視される前提)\n", + "module.exports = { isPalindrome };\n", + "\n", + "Analyze Complexity\n", + "Runtime 4 ms\n", + "Beats 89.77%\n", + "Memory 63.41 MB\n", + "Beats 75.24%\n", + "\n", + "```\n", + "\n", + "---\n", + "\n", + "## 5. 追加メモ(JS最適化チェックリストとの対応)\n", + "\n", + "---\n", + "\n", + "* ループは `while` のみ使用し、`forEach` / `map` などの高階関数は未使用\n", + "* 一時オブジェクト / 配列の生成なし(`number` 変数のみ)\n", + "* 変数はすべて Number 型で固定(hidden class 安定)\n", + "* 破壊的更新はローカル変数 `original` / `revertedHalf` のみで完結(Pure function 条件を維持)\n", + "* 例外は関数冒頭のガードでのみ発生し、ホットパスから切り離し済み\n", + "\n", + "この形であれば、競技プログラミング/業務コード両方の観点で十分実用的かつ拡張しやすい実装になっています。\n", + "\n", + "結論から言うと、そのスコアだと**アルゴリズム的な改善余地はほぼありません**。\n", + "4ms / 上位約90%・メモリ上位約75% は、LeetCode の Node.js 実行環境だと十分「トップクラス寄り」です。\n", + "\n", + "ただし、「スコアをもう少しだけ盛りたい」という観点での**マイクロ最適化**はいくつかあります。\n", + "\n", + "---\n", + "\n", + "## 1. どこに改善余地があるか\n", + "\n", + "### アルゴリズム面\n", + "\n", + "* すでに `O(d)` 時間 / `O(1)` 追加メモリ(d = 桁数) の最適クラス。\n", + "* 文字列を使わず半分だけ反転する解法は、理論的にも LeetCode 的にも定石です。\n", + "* よって、ここから先はアルゴリズム変更ではなく**実装レベルの微調整**になります。\n", + "\n", + "### LeetCode スコア特有の事情\n", + "\n", + "* Runtime / Memory は\n", + "\n", + " * 同じコードでも再提出で数ms・数MB単位でブレる\n", + " * プラットフォーム側の GC タイミング・他ユーザ負荷などに左右される\n", + "* そのため、「4ms → 3ms」を安定して出すのは現実的ではなく、\n", + " あくまで**ノイズの中の運ゲー要素**がかなり大きいです。\n", + "\n", + "---\n", + "\n", + "## 2. マイクロ最適化ポイント\n", + "\n", + "### 2.1 LeetCode 用に「入力バリデーションを削る」\n", + "\n", + "LeetCode は\n", + "\n", + "* 入力は必ず問題文の制約を満たす\n", + "* 型崩れした変数が飛んでくることはない\n", + "\n", + "という前提なので、以下は**スコアを気にするなら削ってよい**です。\n", + "\n", + "* `typeof x !== 'number'` チェック\n", + "* `Number.isFinite(x)` チェック\n", + "* `Number.isInteger(x)` チェック\n", + "* 32bit 範囲チェック\n", + "\n", + "これらは実務コードとしては有用ですが、LeetCode スコアには確実に不利です。\n", + "\n", + "> 実務用: バリデーション入りバージョン\n", + "> LeetCode 用: バリデーション抜きで最小ロジック\n", + "> …とファイルを分けておくのが現実解です\n", + "\n", + "### 2.2 `Math.trunc` をビット演算に置き換える\n", + "\n", + "`original` は途中から常に 0 以上(負数は早期 return 済み)で、かつ 32bit 範囲内です。\n", + "なので\n", + "\n", + "```js\n", + "original = Math.trunc(original / 10);\n", + "```\n", + "\n", + "は\n", + "\n", + "```js\n", + "original = (original / 10) | 0;\n", + "```\n", + "\n", + "に置き換え可能です。\n", + "\n", + "* `/ 10` の結果を 32bit 整数に落とすことで `floor` 相当\n", + "* 32bit 範囲内なら `Math.trunc` と同じ結果\n", + "* V8 的にはビット演算の方が最適化されやすいケースが多い\n", + "\n", + "※ 注意: 一般論としては 2^31 を超える値でビット演算すると壊れますが、この問題は範囲が 32bit 制約なので安全です。\n", + "\n", + "### 2.3 単桁の早期 return\n", + "\n", + "`0〜9` は必ず回文なので、先に弾いておくとループに入るケースが減ります。\n", + "\n", + "```js\n", + "if (x >= 0 && x < 10) return true;\n", + "```\n", + "\n", + "※ すでに負数は弾いている前提。\n", + "\n", + "体感的には微々たる差ですが、コードの意図も明確になるのでアリです。\n", + "\n", + "---\n", + "\n", + "## 3. LeetCode スコア最優先版コード(文字列不使用)\n", + "\n", + "テンプレに沿いつつ、**LeetCode 本番提出用に余計なチェックを除いた版**を示します。\n", + "\n", + "```javascript\n", + "'use strict';\n", + "\n", + "/**\n", + " * 判定対象の整数が 10 進表記で回文かどうかを返す(LeetCode 用軽量版)。\n", + " *\n", + " * 条件:\n", + " * - -2^31 <= x <= 2^31 - 1 (LeetCode 側が保証)\n", + " * - 入力は常に number 型の整数(LeetCode 側が保証)\n", + " *\n", + " * Time Complexity: O(d) (d は x の桁数)\n", + " * Space Complexity: O(1)\n", + " *\n", + " * @param {number} x - 判定対象の 32bit 符号付き整数\n", + " * @returns {boolean} 回文であれば true, そうでなければ false\n", + " */\n", + "var isPalindrome = function (x) {\n", + " // 負数は \"-\" が付くので回文にならない\n", + " if (x < 0) return false;\n", + "\n", + " // 0〜9 は必ず回文\n", + " if (x < 10) return true;\n", + "\n", + " // 0 以外で末尾が 0 の数も回文にならない(先頭が 0 になりえないため)\n", + " if (x % 10 === 0) return false;\n", + "\n", + " let revertedHalf = 0;\n", + "\n", + " // 右半分を反転しながら左半分と比較できる状態まで進める\n", + " while (x > revertedHalf) {\n", + " const digit = x % 10;\n", + " revertedHalf = revertedHalf * 10 + digit;\n", + " // 32bit 整数内で安全なビット演算による整数除算(Math.trunc より軽量)\n", + " x = (x / 10) | 0;\n", + " }\n", + "\n", + " // 偶数桁: x === revertedHalf\n", + " // 奇数桁: 中央 1 桁を捨てるため revertedHalf を 10 で割って比較\n", + " return x === revertedHalf || x === ((revertedHalf / 10) | 0);\n", + "};\n", + "\n", + "// module.exports = { isPalindrome }; // ローカルで試すときだけ有効化\n", + "\n", + "Analyze Complexity\n", + "Runtime 4 ms\n", + "Beats 89.77%\n", + "Memory 63.55 MB\n", + "Beats 70.96%\n", + "\n", + "```\n", + "\n", + "---\n", + "\n", + "## 4. メモリについて\n", + "\n", + "* このアルゴリズム自体は**純粋に O(1) 空間**です。\n", + "* LeetCode が表示する「Memory 63MB」は、\n", + "\n", + " * Node.js ランタイム + テストハーネス + 入出力バッファなど\n", + " * ほぼ「環境の固定コスト」であり、問題側で削れる余地は非常に小さいです。\n", + "* つまり、今の値は**ほぼ限界ライン**と思って良いです。\n", + "\n", + "---\n", + "\n", + "## まとめ\n", + "\n", + "* 現状の 4ms / 89.77%・63MB / 75% は、アルゴリズム的にはほぼ最良クラス。\n", + "* もし「ランキング上で少しでも上を目指したい」という目的なら、\n", + "\n", + " * 入力バリデーションを外す\n", + " * `Math.trunc` をビット演算に変える\n", + " * 単桁を早期 return\n", + " を入れた軽量版を LeetCode 用として分けるのが現実的です。\n", + "\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "javascript" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_py.ipynb b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_py.ipynb new file mode 100644 index 00000000..055215a5 --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_py.ipynb @@ -0,0 +1,422 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "d9092b3b", + "metadata": {}, + "source": [ + "### 1. 問題分析結果\n", + "\n", + "#### 競技プログラミング視点\n", + "\n", + "* 入力: 32bit 符号付き整数 `x`(`-2^31 <= x <= 2^31 - 1`)\n", + "* 出力: `x` が 10 進表記で回文かどうか(左右対称かどうか)の真偽値\n", + "* 桁数を `d` とすると、理想的なオーダーは:\n", + "\n", + " * 時間計算量: `O(d)`(≒ `O(log10 |x|)`)\n", + " * 空間計算量: `O(1)` 追加メモリ\n", + "* 素朴なアプローチ:\n", + "\n", + " * `str(x)` に変換して左右から比較(実装簡単だが、Follow up: “without converting to string” を満たさない)\n", + "* 最適アプローチ(競プロ的にも定石):\n", + "\n", + " * 数値のまま「右半分だけ反転して左半分と比較」する\n", + " * 不要なオブジェクトを作らず、整数演算だけで完結\n", + "\n", + "競プロ用としては以下を徹底します:\n", + "\n", + "* 負数・末尾 0(ただし 0 自身は OK)を早期 return で弾く\n", + "* ループ内は整数演算のみ(`//` と `%`)\n", + "* 追加の list / str / dict / set は一切作らない\n", + "\n", + "#### 業務開発視点\n", + "\n", + "* 可読性・保守性:\n", + "\n", + " * 関数名・docstring で仕様を明示\n", + "\n", + " * 負数は必ず `False`\n", + " * 0 以外で末尾 0 の数は `False`\n", + " * 10 進数での回文判定であること\n", + " * 変数名は `reverted_half`, `remaining` など、役割が分かる命名\n", + "* 型安全性:\n", + "\n", + " * `x: int` / `-> bool` を明示し、pylance での補完・検査をフル活用\n", + " * 本問題は単純なスカラー型なのでジェネリクスは不要\n", + "* エラーハンドリング:\n", + "\n", + " * プロダクション版では「外部からの入力」を想定して `isinstance(x, int)` や値域チェックを実装\n", + " * 競プロ版ではパフォーマンス優先でバリデーションを省略\n", + "\n", + "#### Python特有分析\n", + "\n", + "* データ構造選択:\n", + "\n", + " * 単なる整数演算なので、`list` / `deque` / `dict` などは不要\n", + " * 追加の組み込みデータ構造を使わないほうが GC 負荷も減り、速度も安定\n", + "* CPython / 実装最適化:\n", + "\n", + " * Python の `int` は任意精度だが、この問題の範囲内ならオーバーフローの心配は不要\n", + " * `//` と `%` は C レベルで実装されており十分高速\n", + " * ループ内での属性アクセスや関数呼び出しを最小化(ローカル変数だけで閉じる)\n", + "* GIL:\n", + "\n", + " * 完全な CPU バウンド & 単一スレッドの問題なので、GIL はまったく問題にならない\n", + "\n", + "---\n", + "\n", + "### 2. アルゴリズムアプローチ比較\n", + "\n", + "| アプローチ | 時間計算量 | 空間計算量 | Python実装コスト | 可読性 | 標準ライブラリ活用 | CPython最適化 | 備考 |\n", + "| ----------------- | ----- | ----- | ----------- | --- | --------- | ---------- | ------------------------------------ |\n", + "| 方法A: 文字列変換 + 両端比較 | O(d) | O(d) | 低 | ★★★ | `str` だけ | まあまあ | Follow up 不満足。実装は最短 |\n", + "| 方法B: 半分だけ数値反転(採用) | O(d) | O(1) | 中 | ★★☆ | なし | 非常に良い | 文字列変換なし。整数演算のみ |\n", + "| 方法C: 全体を数値反転して比較 | O(d) | O(1) | 中 | ★★☆ | なし | 良い | `rev == x` 比較。大きな数ではオーバーフロー考慮が必要な言語も |\n", + "\n", + "※ ここで `d` は桁数(≒ `log10 |x|`)\n", + "\n", + "この問題では:\n", + "\n", + "* Follow up 条件(文字列変換禁止)を満たす必要がある\n", + "* 追加メモリ `O(1)` を達成できる\n", + "* CPython では整数演算は C 実装で高速\n", + "\n", + "という点から、**方法B(半分だけ数値反転)**を採用します。\n", + "\n", + "---\n", + "\n", + "### 3. 採用アルゴリズムと根拠\n", + "\n", + "#### アルゴリズム概要(方法B)\n", + "\n", + "1. 負数は `False`(先頭に `-` が付くため回文にならない)\n", + "2. `x != 0` かつ `x` の末尾が 0 の場合は `False`\n", + "\n", + " * 例: `10 → \"01\"` とは読めないので回文ではない\n", + "3. 右側の半分だけを反転した整数 `reverted` を作る:\n", + "\n", + " * `digit = x % 10`\n", + " * `reverted = reverted * 10 + digit`\n", + " * `x //= 10`\n", + " * これを `x <= reverted` になるまで繰り返す\n", + "4. ループ終了後:\n", + "\n", + " * 偶数桁: `x == reverted` なら回文\n", + " * 奇数桁: 中央 1 桁を無視して `x == reverted // 10` なら回文\n", + "\n", + "#### 選択理由\n", + "\n", + "* **計算量的な優位性**\n", + "\n", + " * 時間 `O(d)` / 空間 `O(1)` と、文字列変換込みの方法よりメモリ効率が良い\n", + "* **Python環境での型安全性**\n", + "\n", + " * `x: int` → `bool` の単純な型シグネチャで十分\n", + " * 内部もすべて `int` のみで完結し、型崩れの余地がない\n", + "* **保守性・可読性**\n", + "\n", + " * ロジック自体は定石であり、コメントを添えれば理解しやすい\n", + " * `isPalindrome` を競プロ版としてシンプルに保ちつつ、\n", + " プロダクション用に別メソッドでバリデーションを厚めにする構成が取りやすい\n", + "\n", + "#### Python最適化戦略\n", + "\n", + "* 標準ライブラリをあえて使わず、整数演算のみで完結させる\n", + "\n", + " * `collections`, `deque`, `heapq` 等は不要(この問題ではオーバーエンジニアリング)\n", + "* ループ内をシンプルなローカル変数だけにして、CPython の最適化(バイトコード・ローカル変数アクセス)を活かす\n", + "* 例外・バリデーションは別メソッドに切り出し、競プロ用ホットパスから除外\n", + "\n", + "---\n", + "\n", + "### 4. 実装パターン(業務版 + 競プロ版)\n", + "\n", + "* LeetCode が呼び出すのは `Solution.isPalindrome(self, x: int) -> bool` のみ\n", + "* 業務/学習用途も想定して、クラス内に「業務開発版」として別メソッドを定義\n", + "* `isPalindrome` は競プロ版(バリデーション無し)として最小構成で実装\n", + "\n", + "---\n", + "\n", + "### 5. 実装コード(LeetCode 用/Class形式・pylance対応)\n", + "\n", + "```python\n", + "from __future__ import annotations\n", + "\n", + "from typing import Final\n", + "\n", + "\n", + "class Solution:\n", + " \"\"\"\n", + " Palindrome Number 判定クラス\n", + "\n", + " LeetCode からは isPalindrome(x) のみが呼び出される。\n", + " - isPalindrome: 競技プログラミング向け(性能最優先・バリデーション省略)\n", + " - is_palindrome_production: 業務開発向け(入力検証あり、任意利用)\n", + " \"\"\"\n", + "\n", + " def isPalindrome(self, x: int) -> bool:\n", + " \"\"\"\n", + " 整数 x が 10 進表記で回文かどうかを判定する(競技プログラミング向け)。\n", + "\n", + " このメソッドは LeetCode が直接呼び出すエントリポイント。\n", + " 入力は LeetCode が制約を保証しているため、追加の型検証は行わない。\n", + "\n", + " Args:\n", + " x: 判定対象の整数(LeetCode 上では 32bit 符号付き整数)\n", + "\n", + " Returns:\n", + " x が 10 進表記で回文であれば True、そうでなければ False。\n", + "\n", + " Time Complexity:\n", + " O(d) (d は x の桁数 ≒ log10(|x|))\n", + "\n", + " Space Complexity:\n", + " O(1) 追加メモリは定数個の整数のみ。\n", + " \"\"\"\n", + " # 負数、0 以外で末尾が 0 の数は回文にならない\n", + " if x < 0 or (x % 10 == 0 and x != 0):\n", + " return False\n", + "\n", + " # 0〜9 は必ず回文\n", + " if x < 10:\n", + " return True\n", + "\n", + " reverted: int = 0\n", + "\n", + " # 右半分を反転しつつ、左半分と比較できる状態まで進める\n", + " # ループを抜ける条件:\n", + " # - 偶数桁: x と reverted が同じ桁数になった時点で x <= reverted\n", + " # - 奇数桁: 中央 1 桁を含んだ reverted の方が 1 桁多くなった時点で x < reverted\n", + " while x > reverted:\n", + " digit: int = x % 10\n", + " reverted = reverted * 10 + digit\n", + " x //= 10 # 整数除算で末尾 1 桁を捨てる\n", + "\n", + " # 偶数桁: x == reverted\n", + " # 奇数桁: 中央 1 桁を無視するため、reverted // 10 と比較\n", + " return x == reverted or x == reverted // 10\n", + "\n", + "Analyze Complexity\n", + "Runtime 8 ms\n", + "Beats 51.90%\n", + "Memory 17.78 MB\n", + "Beats 63.74%\n", + "\n", + " # ---- 以下は業務開発向けの参考実装(LeetCode からは呼ばれない) ----\n", + "\n", + " def is_palindrome_production(self, x: int) -> bool:\n", + " \"\"\"\n", + " 業務開発向けの回文判定メソッド。\n", + "\n", + " - 型安全性・エラーハンドリングを重視\n", + " - 32bit 符号付き整数の制約を明示的に検証\n", + "\n", + " Args:\n", + " x: 判定対象の整数\n", + "\n", + " Returns:\n", + " x が 10 進表記で回文であれば True、そうでなければ False。\n", + "\n", + " Raises:\n", + " TypeError: x が int でない場合\n", + " ValueError: x が 32bit 符号付き整数の範囲外の場合\n", + " \"\"\"\n", + " if type(x) is not int:\n", + " raise TypeError(\"x must be an int, not bool or other types\")\n", + "\n", + " int_min: Final[int] = -2 ** 31\n", + " int_max: Final[int] = 2 ** 31 - 1\n", + " if x < int_min or x > int_max:\n", + " raise ValueError(\"x must be a 32-bit signed integer\")\n", + "\n", + " # 入力検証が済めば、あとは競プロ版ロジックをそのまま再利用\n", + " return self.isPalindrome(x)\n", + "```\n", + "\n", + "---\n", + "\n", + "### 6. 簡易検証観点(コード内コメントレベル)\n", + "\n", + "※ 実際にここでテストコードを書く必要はない前提で、どのように検証するかの観点だけ整理します。\n", + "\n", + "* 境界値:\n", + "\n", + " * `x = 0` → True\n", + " * `x = 1` / `9` → True\n", + " * `x = 10` / `100` / `-1` → False\n", + " * `x = 121` / `1221` → True\n", + " * `x = -121` → False\n", + " * `x = 2**31 - 1 = 2147483647` → False\n", + " * `x = -2**31 = -2147483648` → False\n", + "* 制約限界:\n", + "\n", + " * `x = 1000000001`(10 桁)など桁数の多いケースでも問題なく動作すること\n", + "* 型チェック(業務版のみ):\n", + "\n", + " * `x = 1.0` / `\"121\"` / `None` で `TypeError`\n", + " * `x = 2**31` 等で `ValueError`\n", + "\n", + "この構成であれば:\n", + "\n", + "* LeetCode 用の `isPalindrome` は最小限かつ高速\n", + "* 業務開発向けにもそのまま流用できるクリアなクラス構成\n", + "* 型ヒントはすべて明示されており、pylance でもエラーなく解析可能\n", + "\n", + "というバランスになっています。\n", + "\n", + "結論だけ言うと、\n", + "\n", + "* **アルゴリズムとしては最適クラス(O(d), O(1))なので大きな改善余地はありません**\n", + "* ただし、**LeetCode の Python 実行環境特有のマイクロ最適化**で、もう少しだけ速くなる可能性はあります(とはいえノイズレベル)\n", + "\n", + "というポジションです。\n", + "\n", + "---\n", + "\n", + "## 1. 数値アルゴリズムとしての改善余地\n", + "\n", + "既に「数値のまま右半分だけ反転して比較」という解法であれば:\n", + "\n", + "* 時間計算量: `O(d)`(d = 桁数)\n", + "* 空間計算量: `O(1)`(定数個の `int` のみ)\n", + "\n", + "なので、**理論的にはこれ以上良くなりません**。\n", + "\n", + "`8ms / Beats 51.90%` というのは、\n", + "\n", + "* Python 提出全体の「ちょうど真ん中〜やや上」\n", + "* ここから先は「環境ノイズ + 実装ディテール勝負」\n", + "\n", + "という世界です。\n", + "\n", + "---\n", + "\n", + "## 2. Python / LeetCode 向け マイクロ最適化ポイント\n", + "\n", + "### 2-1. 競プロ用にコードを「最小構成」に削る\n", + "\n", + "前回のように docstring や業務用メソッドを入れていると、\n", + "\n", + "* モジュールロードのコスト\n", + "* クラス定義のコスト\n", + "\n", + "が多少は載ります(とはいえ本当にわずかですが)。\n", + "\n", + "**LeetCode の計測は「テストケース実行込み」で測っているので、最小構成に寄せる価値はあります。**\n", + "\n", + "競プロ専用に、以下のような「必要最低限」に削った版を用意するのはアリです。\n", + "\n", + "```python\n", + "class Solution:\n", + " def isPalindrome(self, x: int) -> bool:\n", + " # 負数、0 以外で末尾が 0 の数は回文にならない\n", + " if x < 0 or (x % 10 == 0 and x != 0):\n", + " return False\n", + "\n", + " # 0〜9 は 1 桁なので必ず回文\n", + " if x < 10:\n", + " return True\n", + "\n", + " rev: int = 0\n", + "\n", + " # 右半分を反転しつつ、左半分と比較できる状態まで進める\n", + " while x > rev:\n", + " rev = rev * 10 + (x % 10)\n", + " x //= 10\n", + "\n", + " # 偶数桁: x == rev\n", + " # 奇数桁: 中央 1 桁を無視するため rev // 10 と比較\n", + " return x == rev or x == rev // 10\n", + "\n", + "Analyze Complexity\n", + "Runtime 6 ms\n", + "Beats 66.55%\n", + "Memory 18.01 MB\n", + "Beats 19.33%\n", + "\n", + "```\n", + "\n", + "ポイント:\n", + "\n", + "* クラス内は `isPalindrome` のみ\n", + "* 型ヒントは `x: int` / `-> bool` のみ(pylance OK)\n", + "* ループ内は単純な整数演算だけ\n", + "\n", + "### 2-2. 文字列アプローチとのトレードオフ\n", + "\n", + "正直なところ、**LeetCode の Python では「文字列変換版」の方が速く出るケースもあります**。\n", + "\n", + "```python\n", + "class Solution:\n", + " def isPalindrome(self, x: int) -> bool:\n", + " if x < 0:\n", + " return False\n", + " s = str(x)\n", + " return s == s[::-1]\n", + "\n", + "Analyze Complexity\n", + "Runtime 8 ms\n", + "Beats 51.90%\n", + "Memory 17.69 MB\n", + "Beats 88.86%\n", + "\n", + "```\n", + "\n", + "* `str()` やスライスは C 実装なので非常に高速\n", + "* 数値版と比べてアルゴリズム的には同じ `O(d)` ですが、定数倍が小さいことも多い\n", + "\n", + "ただし:\n", + "\n", + "* Follow up の「文字列変換なしで解けるか?」という要件は満たさない\n", + "* 「Follow up も満たしたいか」「スコアだけ取りに行きたいか」で使い分けになる\n", + "\n", + "**Follow up も意識しているなら、今の数値版の方が“解としては正統派”**です。\n", + "\n", + "### 2-3. 計測値のブレを前提にする\n", + "\n", + "Python / LeetCode の Runtime は:\n", + "\n", + "* 同じコードでも、再提出すると 6ms〜10ms くらいは普通にブレます\n", + "* GC タイミング・他のテストの組み合わせ・サーバ負荷などに依存\n", + "\n", + "ですので、\n", + "\n", + "* コードをかなり削っても、必ずしも 51% → 80% みたいに上がる保証はありません\n", + "* 実際には「何回か提出してみたら 6ms / 7ms が出た」というケースもよくあります\n", + "\n", + "---\n", + "\n", + "## 3. メモリについて\n", + "\n", + "`17.78MB / Beats 63.74%` は Python としてはかなり健全な数字です。\n", + "\n", + "* この関数が追加で使っているメモリは **数個の `int` だけ**\n", + "* 残りは「Python ランタイム + テストドライバ」の固定コストがほとんど\n", + "\n", + "したがって、\n", + "\n", + "* **アルゴリズムレベルでメモリをさらに削る余地はほぼゼロ**\n", + "* これ以上の改善は「環境依存ノイズの範囲内」と考えて問題ありません\n", + "\n", + "---\n", + "\n", + "## 4. まとめ\n", + "\n", + "* アルゴリズムは最適クラスで、Python実装としても十分高速です。\n", + "* 改善余地があるとすれば:\n", + "\n", + " * LeetCode 用にクラス・メソッドを**最小構成**にする\n", + " * Follow up を気にしないなら、**文字列版でスコアを取りに行く**、という選択肢もある\n", + "* ただし、どちらにせよ計測値はノイズが大きいので、**51% という数字自体をあまり気にしすぎなくて大丈夫**です。\n", + "\n" + ] + } + ], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_ts.ipynb b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_ts.ipynb new file mode 100644 index 00000000..286fffea --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/PalindromeNumber_ts.ipynb @@ -0,0 +1,368 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8bd90dbf", + "metadata": {}, + "source": [ + "# 1. 問題の分析\n", + "\n", + "---\n", + "\n", + "## 競技プログラミング視点での分析\n", + "\n", + "- 入力: 32bit 符号付き整数 `x`(`-2^31 <= x <= 2^31 - 1`)\n", + "- 出力: `x` が 10 進表記で左右対称かどうか(回文かどうか)の真偽値\n", + "- 桁数を `d` とすると、理想は\n", + " - 時間計算量: `O(d)`(≒ `O(log10 |x|)`)\n", + " - 空間計算量: `O(1)` 追加メモリ\n", + "\n", + "- 典型的アプローチ:\n", + " - 文字列に変換して左右から比較(簡単だが Follow up では NG)\n", + " - 数値のまま桁を扱い、半分だけ反転して比較(Follow up 対応・最適)\n", + "\n", + "競プロ視点では:\n", + "\n", + "- 負数・末尾 0(ただし 0 自体は OK)を早期 return で弾く\n", + "- ループ内は整数演算のみ\n", + "- 追加オブジェクト・配列を生成しない\n", + "\n", + "これで実行速度・メモリともにほぼ最適です。\n", + "\n", + "### 業務開発視点での分析\n", + "\n", + "- LeetCode 上はバリデーション不要だが、業務では以下を設計レベルで決める:\n", + " - 型: 引数は `number` だが、**整数のみ**を前提とする仕様であることを明示\n", + " - 範囲: 32bit のみを許容するのか、汎用 `number` として扱うのか\n", + "\n", + "- 本問題の実装自体は小さいため、保守性のポイントは:\n", + " - 関数名・コメントで「10 進回文判定」「負数は false」「末尾 0 の扱い」などを明示\n", + " - 中間変数名は `revertedHalf` / `remaining` 等、意図が分かる名前を使う\n", + "\n", + "- エラーハンドリング:\n", + " - TypeScript 側の型 `x: number` で「非 number」をコンパイル時に排除\n", + " - 実行時の追加チェックはこの規模だとコスト > メリットになりやすいので、\n", + " 「外部 API 境界で検証 + この関数は信頼された値を前提」にする設計が現実的\n", + "\n", + "### TypeScript特有の考慮点\n", + "\n", + "- 型推論:\n", + " - この問題は引数・戻り値ともプリミティブなためジェネリクス不要\n", + " - 明示的に `x: number`, `: boolean` を指定すれば十分\n", + "\n", + "- strict mode:\n", + " - `noImplicitAny` / `strictNullChecks` などの影響はほぼなく、素直に書けばコンパイルエラーにはならない\n", + "\n", + "- コンパイル時最適化:\n", + " - 単純な算術演算 + 比較のみのため、TS → JS トランスパイルでほぼコストゼロ\n", + " - 余計な抽象化(ジェネリクス・ユーティリティ型)はかえって V8 最適化を妨げる可能性があるので、この関数自体はシンプルに保つのが得策\n", + "\n", + "---\n", + "\n", + "## 2. アルゴリズムアプローチ比較\n", + "\n", + "| アプローチ | 時間計算量 | 空間計算量 | TS実装コスト | 型安全性 | 可読性 | 備考 |\n", + "| ----------------------------------- | ---------- | ---------- | ------------ | -------- | ------ | --------------------------------------------------------- |\n", + "| 方法A: 文字列変換 + 両端比較 | O(d) | O(d) | 低 | 高 | 高 | `x.toString()` → 配列インデックスで比較。Follow up 不満足 |\n", + "| 方法B: 数値を半分だけ反転(採用案) | O(d) | O(1) | 中 | 高 | 中〜高 | 文字列不使用。左右半分を数値のまま比較 |\n", + "| 方法C: 数値全体を反転して比較 | O(d) | O(1) | 中 | 高 | 中 | `rev = rev * 10 + digit` で全体反転 → `rev === x` を比較 |\n", + "\n", + "- TS実装コスト:\n", + " - どれも数行〜十数行レベルだが、文字列版が最も短い\n", + "\n", + "- 型安全性:\n", + " - 3 つとも「`x: number` → `boolean`」で完結するため差は小さい\n", + " - ただし文字列変換版は「内部で string を扱う」ため、型としてはやや複合的\n", + "\n", + "---\n", + "\n", + "## 3. 選択したアルゴリズムと理由\n", + "\n", + "- **選択したアプローチ**: 方法B(数値を半分だけ反転して比較)\n", + "\n", + "### 理由\n", + "\n", + "1.**計算量的な優位性**\n", + "\n", + "- 時間:`O(d)` / 空間: `O(1)` と最適クラス\n", + "- 文字列変換版よりもメモリ的に有利(余分な string / 配列を作らない)\n", + "\n", + "2.**TypeScript環境での型安全性**\n", + "\n", + "- インターフェースは単純な `isPalindrome(x: number): boolean`\n", + "- 中間変数もすべて `number` 固定で、型崩れの余地がない\n", + "- strict mode でも追加の型注釈をほぼ必要としない\n", + "\n", + "3.**保守性・可読性**\n", + "\n", + "- 数値アルゴリズムとして定石かつ、コメントを添えれば挙動は明瞭\n", + "- 仕様(負数は false / 末尾 0)を冒頭で明示し、理解しやすい分岐に分解できる\n", + "\n", + "### TypeScript特有の最適化ポイント\n", + "\n", + "- コンパイル時の型チェック:\n", + " - `x: number` により、呼び出し側で `string` や `null` をコンパイル時に拒否可能\n", + "\n", + "- 型推論:\n", + " - ループ内変数はすべて `number` と推論され、V8 側でも単型のまま扱われやすい\n", + "\n", + "- 過剰なジェネリクスを避ける:\n", + " - この関数は **汎用アルゴリズムというよりドメイン固有の判定関数** なので、\n", + " ジェネリクスを使わずシンプルなシグネチャで固定するほうがメンテナンス性が高い\n", + "\n", + "---\n", + "\n", + "## 4. 実装コード(LeetCode 用 TypeScript/ESM想定)\n", + "\n", + "LeetCode の TypeScript では、基本的に「グローバルに関数宣言」だけを書くのがフォーマットです。\n", + "ESM で Node.js から利用する場合は、この関数を `export` すればよいですが、ここでは **LeetCode 提出用フォーマット** に合わせて関数のみ記載します。\n", + "\n", + "```ts\n", + "/**\n", + " * 整数 x が 10 進表記で回文かどうかを判定する。\n", + " *\n", + " * 定義:\n", + " * - x を 10 進数表記したとき、左から読んでも右から読んでも同じなら true。\n", + " * - 負数は必ず false(先頭に '-' が付くため)。\n", + " *\n", + " * 例:\n", + " * - 121 → true\n", + " * - -121 → false\n", + " * - 10 → false\n", + " *\n", + " * @param x - 判定対象の 32bit 符号付き整数\n", + " * @returns x が回文であれば true, そうでなければ false\n", + " * @complexity Time: O(d), Space: O(1)\n", + " * - d は x の桁数(≒ log10(|x|))\n", + " */\n", + "function isPalindrome(x: number): boolean {\n", + " // 負数は先頭に '-' が付くので回文にならない\n", + " if (x < 0) return false;\n", + "\n", + " // 0〜9 は必ず 1 桁なので回文\n", + " if (x < 10) return true;\n", + "\n", + " // 0 以外で末尾が 0 の数は回文にならない\n", + " // 例: 10 → \"01\" とは読めないため\n", + " if (x % 10 === 0) return false;\n", + "\n", + " // revertedHalf: 右側半分を反転して作られる数\n", + " let revertedHalf = 0;\n", + " let remaining = x;\n", + "\n", + " // remaining(左側の残りの数)が revertedHalf(右側反転)より大きい間は処理を続ける\n", + " // これにより「半分だけ」反転する\n", + " while (remaining > revertedHalf) {\n", + " const digit = remaining % 10; // 末尾の 1 桁を取り出す\n", + " revertedHalf = revertedHalf * 10 + digit; // 右側反転数の末尾に桁を追加\n", + " remaining = Math.trunc(remaining / 10); // 末尾 1 桁を捨てる(整数除算)\n", + " }\n", + "\n", + " // 偶数桁:\n", + " // 例) 1221 → remaining = 12, revertedHalf = 12\n", + " // 奇数桁:\n", + " // 例) 12321 → remaining = 12, revertedHalf = 123\n", + " // 真ん中の 3 は回文判定に影響しないので、revertedHalf を 10 で割って捨てる\n", + " return remaining === revertedHalf || remaining === Math.trunc(revertedHalf / 10);\n", + "}\n", + "\n", + "Analyze Complexity\n", + "Runtime 5 ms\n", + "Beats 81.22%\n", + "Memory 64.67 MB\n", + "Beats 83.89%\n", + "\n", + "```\n", + "\n", + "- Pure function:\n", + " - グローバル状態の変更・I/O は一切なく、同じ `x` に対して常に同じ結果を返します。\n", + "\n", + "- 型安全性:\n", + " - 引数は `number`、戻り値は `boolean` と明示\n", + " - LeetCode 側が「32bit 整数のみ」を保証しているため、追加のランタイム検証は不要\n", + "\n", + "- 実行時性能:\n", + " - 文字列変換なし\n", + " - 定数個の `number` 変数のみを使用\n", + " - ループは整数演算のみで `O(d)` / `O(1)` を達成\n", + "\n", + "---\n", + "\n", + "もし業務利用も視野に入れて、「外部からの入力を直接受けるバリデーション付きラッパ関数」「Node.js ESM での export 形態」なども一緒に整理したい場合は、そこも TypeScript の型で固めた設計案を出せます。\n", + "\n", + "結論から言うと、そのスコアなら**アルゴリズム的な改善余地はほぼありません**。\n", + "`5ms / Beats 81%`・`64MB / Beats 83%` は、LeetCode TypeScript 環境としては十分ハイレベルです。\n", + "\n", + "ただ、「**競プロ視点でもう少しだけ攻める**」という意味での**マイクロ最適化**はあります。\n", + "\n", + "---\n", + "\n", + "## 1. 状況整理:どこまでやれば「改善」なのか\n", + "\n", + "- 時間計算量: 既に `O(d)`(d は桁数)・これ以上は理論的に削れません。\n", + "- 空間計算量: 追加メモリ `O(1)`・これも最適です。\n", + "- LeetCode の Runtime/Memory は:\n", + " - 同じコードでも再提出で 3〜6ms くらい平気でブレます\n", + " - メモリも「JSランタイム+テストハーネス」の固定コストが大半\n", + "\n", + "なので、今からやるのは**「理論改善」ではなく「実装ディテール調整+運ゲーを少しだけ味方にする」**レベルになります。\n", + "\n", + "---\n", + "\n", + "## 2. マイクロ最適化の候補\n", + "\n", + "### 2.1 `Math.trunc` を 32bit ビット演算に置き換える\n", + "\n", + "現在のような\n", + "\n", + "```ts\n", + "remaining = Math.trunc(remaining / 10);\n", + "```\n", + "\n", + "よりも、32bit 整数に丸めるビット演算の方が V8 的に速いことが多いです。\n", + "\n", + "```ts\n", + "remaining = (remaining / 10) | 0;\n", + "```\n", + "\n", + "この問題は元々「32bit 符号付き整数」制約なので、ビット演算による 32bit 化は安全です。\n", + "\n", + "### 2.2 パラメータ `x` をそのまま破壊的に使う\n", + "\n", + "現在:\n", + "\n", + "```ts\n", + "let remaining = x;\n", + "let revertedHalf = 0;\n", + "// ...\n", + "remaining = ...;\n", + "```\n", + "\n", + "としているなら、**ローカル変数を一つ減らして** `x` 自体を更新してしまう手もあります。\n", + "\n", + "```ts\n", + "let reverted = 0;\n", + "while (x > reverted) {\n", + " reverted = reverted * 10 + (x % 10);\n", + " x = (x / 10) | 0;\n", + "}\n", + "```\n", + "\n", + "- JS/TS 的には引数を書き換えても問題ありません(Pure さは「外部状態を変えない」かどうかで見る)。\n", + "- 変数が 1 個減る程度なので差はごくわずかですが、V8 の最適化的にはプラスに働く可能性があります。\n", + "\n", + "### 2.3 条件分岐の簡略化\n", + "\n", + "今は\n", + "\n", + "```text\n", + "if (x < 0) return false;\n", + "if (x < 10) return true;\n", + "if (x % 10 === 0) return false;\n", + "```\n", + "\n", + "のようにしていると思いますが、\n", + "\n", + "```text\n", + "if (x < 0 || (x % 10 === 0 && x !== 0)) return false;\n", + "if (x < 10) return true;\n", + "```\n", + "\n", + "のようにまとめると、わずかに分岐数が減ります(可読性とのトレードオフなので好みの範囲)。\n", + "\n", + "---\n", + "\n", + "## 3. スコア特化版 TypeScript 実装例(LeetCode 提出フォーマット)\n", + "\n", + "上記のマイクロ最適化を反映した「**競プロスコア特化版**」を書いておきます。\n", + "LeetCode の TypeScript 用に、余計な export 等は付けていません。\n", + "\n", + "```ts\n", + "/**\n", + " * 整数 x が 10 進表記で回文かどうかを判定する。\n", + " *\n", + " * @param x - 判定対象の 32bit 符号付き整数\n", + " * @returns x が回文であれば true, そうでなければ false\n", + " * @complexity Time: O(d), Space: O(1)\n", + " */\n", + "function isPalindrome(x: number): boolean {\n", + " // 負数、0 以外で末尾が 0 の数は回文にならない\n", + " if (x < 0 || (x % 10 === 0 && x !== 0)) {\n", + " return false;\n", + " }\n", + "\n", + " // 0〜9 は必ず回文\n", + " if (x < 10) {\n", + " return true;\n", + " }\n", + "\n", + " let reverted = 0;\n", + "\n", + " // 右半分を反転しつつ、左半分と比較できる状態まで進める\n", + " while (x > reverted) {\n", + " const digit = x % 10;\n", + " reverted = reverted * 10 + digit;\n", + " // 32bit 整数への切り捨て除算(Math.trunc より軽量)\n", + " x = (x / 10) | 0;\n", + " }\n", + "\n", + " // 偶数桁: x === reverted\n", + " // 奇数桁: 中央 1 桁を捨てるため reverted を 10 で割る\n", + " return x === reverted || x === ((reverted / 10) | 0);\n", + "}\n", + "\n", + "Analyze Complexity\n", + "Runtime 5 ms\n", + "Beats 81.22%\n", + "Memory 64.98 MB\n", + "Beats 72.42%\n", + "\n", + "```\n", + "\n", + "ポイント:\n", + "\n", + "- **アルゴリズムはまったく同じ**(数値を半分だけ反転)\n", + "- `Math.trunc` → `| 0` に変更\n", + "- `remaining` をなくし、`x` そのものを更新\n", + "- 条件分岐を少しまとめて分岐数を削減\n", + "\n", + "---\n", + "\n", + "## 4. メモリについて\n", + "\n", + "`64.67MB / Beats 83.89%` はかなり良い数字で、ここからさらに 1〜2MB 下げることはほぼ不可能です。\n", + "\n", + "- この関数が使っている追加メモリは**ほぼ数個の number だけ**(数十バイトレベル)\n", + "- 残りの 60MB 超は「Node.js ランタイム + LeetCode テストフレームワーク」の固定コスト\n", + "\n", + "つまり、**メモリはもう十分以上に最適化されている**と考えてよいです。\n", + "\n", + "---\n", + "\n", + "## まとめ\n", + "\n", + "- 今のスコアは**実用上ほぼベストクラス**。\n", + "- 改善余地があるとすれば:\n", + " - `Math.trunc` → ビット演算\n", + " - 引数 `x` をそのまま使う(ローカル変数削減)\n", + " - 分岐の簡略化\n", + "\n", + "- ただし、これらを入れても Runtime は環境ノイズに埋もれるレベルの差になるので、\n", + " 「**これ以上は趣味の世界**」という認識で大丈夫です。\n" + ] + }, + { + "cell_type": "markdown", + "id": "d9092b3b", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "language_info": { + "name": "typescript" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/README.md b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/README.md new file mode 100644 index 00000000..96546338 --- /dev/null +++ b/Mathematics/Palindrome/leetcode/9. Palindrome Number/gpt 5.1 thinking customized/README.md @@ -0,0 +1,379 @@ +# Palindrome Number - 整数が回文かを数値だけで判定する + +## Table of Contents + +- [概要](#overview) +- [アルゴリズム要点(TL;DR)](#tldr) +- [図解](#figures) +- [正しさのスケッチ](#correctness) +- [計算量](#complexity) +- [Python 実装](#impl) +- [CPython 最適化ポイント](#cpython) +- [エッジケースと検証観点](#edgecases) +- [FAQ](#faq) + +--- + +

概要

+ +- **問題タイトル**: Palindrome Number + +- **プラットフォーム / ID**: LeetCode 9 + +- **関数シグネチャ**: + + ```python + class Solution: + def isPalindrome(self, x: int) -> bool: + ... + ``` + +- **問題要約**: + - 整数 `x` が 10 進数表記で「左右対称(回文)」かどうかを判定する。 + - 例: + - `121` → `True` + - `-121` → `False`(`-121` vs `121-`) + - `10` → `False`(`10` vs `01`) + +- **入出力仕様(簡潔)**: + - 入力: 整数 `x` (`-2^31 <= x <= 2^31 - 1`) + - 出力: 回文なら `True`、そうでなければ `False` + +- **Follow up**: + 「**整数を文字列に変換せずに**解けるか?」が問われる。 + +この解説では、**文字列変換を使わずに数値だけで判定する O(log10|x|)・O(1) アルゴリズム**と、その Python 実装を扱います。 + +--- + +

アルゴリズム要点(TL;DR)

+ +- 戦略(数値のみ): + - 負数 → 即 `False` + - `0` 以外で末尾が `0` の数 → 即 `False`(先頭に `0` は立てられない) + - `0..9` の 1 桁 → 即 `True` + - それ以外は、**右半分の桁だけを反転**して整数 `rev` を作り、 + - `x == rev`(偶数桁)または + - `x == rev // 10`(奇数桁、中央 1 桁を無視) + なら回文と判定。 + +- データ構造: + - すべて `int`(Python の整数)のみ。配列・文字列・追加構造体は不要。 + +- 想定計算量: + - 時間: `O(d)` (`d` は桁数、≒ `O(log10|x|)`) + - 空間: `O(1)`(定数個の整数だけ) + +- 主要な数値操作: + - `digit = x % 10` で末尾 1 桁 + - `x //= 10` で末尾 1 桁を削除 + - `rev = rev * 10 + digit` で反転側に桁を追加 + +--- + +

図解

+ +### フローチャート(制御フロー) + +```mermaid +flowchart TD + Start[Start with x] + NegOrZeroTail{Check x < 0 or tail zero} + SingleDigit{Check single digit} + Init[Init rev as 0] + LoopCond{Check x > rev} + UpdateRev[Update rev by last digit] + UpdateX[Trim last digit of x] + Compare[Compare left and right halves] + ReturnTrue[Return true] + ReturnFalse[Return false] + + Start --> NegOrZeroTail + NegOrZeroTail -- Yes --> ReturnFalse + NegOrZeroTail -- No --> SingleDigit + SingleDigit -- Yes --> ReturnTrue + SingleDigit -- No --> Init + Init --> LoopCond + LoopCond -- Yes --> UpdateRev + LoopCond -- No --> Compare + UpdateRev --> UpdateX + UpdateX --> LoopCond + Compare --> ReturnTrue + Compare --> ReturnFalse +``` + +- 負数・末尾 0 のパターン・1 桁のパターンを先にフィルタし、その後ループで右側半分を反転して比較する流れを表しています。 + +### データフロー図(x と rev の関係) + +```mermaid +graph LR + subgraph Precheck + A[Input x] --> B[Check sign and tail] + B --> C[Single digit decision] + end + subgraph Core + C --> D[Iterative half reverse] + D --> E[Left half x] + D --> F[Right half rev] + end + E --> G[Compare halves] + F --> G + G --> H[Return boolean] +``` + +- 入力 `x` が事前チェックを通過したあと、コア部で `x` と `rev` の 2 つの整数に分かれ、最終的に「左右の半分を比較して bool を返す」というデータの流れを示しています。 + +--- + +

正しさのスケッチ

+ +このアルゴリズムが常に正しい結果を返す理由を、いくつかの観点から簡潔に整理します。 + +### 1. 事前フィルタの正しさ + +1. **負数** (`x < 0`) + - 10 進表記では必ず先頭に `-` が付くため、左右対称にはなり得ない。 + - よって負数は常に回文ではない → `False` が正しい。 + +2. **末尾が 0 の数** (`x % 10 == 0 and x != 0`) + - 先頭に `0` を付けて表記することはないため、 + - 例: `10` → `"10"` と `"01"` は異なる。 + + - `0` 自体は回文だが、それ以外で末尾が 0 の数は必ず非回文 → `False` が正しい。 + +3. **1 桁の数** (`0 <= x <= 9`) + - 1 桁の数は左右から読んでも同じなので、必ず回文 → `True` が正しい。 + +### 2. ループ中の不変条件(invariant) + +ループ本体では、毎回以下を行います。 + +- `digit = x % 10` で末尾 1 桁を取り出す +- `rev = rev * 10 + digit` で `rev` の末尾にこの桁を追加 +- `x //= 10` で `x` の末尾 1 桁を削除 + +このとき、ループの各反復において次の不変条件が成り立ちます。 + +- `rev` は、**元の数の下位から取り出した桁列の反転**になっている。 +- `x` は、**元の数の上位側が残っている**数になっている。 +- 「現在までに `rev` に取り込んだ桁列」と「`x` に残っている桁列」を並べると、元の `x` の桁列に対応する。 + +### 3. ループ終了条件と偶数/奇数桁の扱い + +ループは `while x > rev:` という条件で回します。 + +- **偶数桁**の場合: + - 例: `1221` + - 途中で `x` と `rev` は同じ桁数になり、最後には `x == rev` となる。 + - このとき `x == rev` であれば左右対称、そうでなければ非対称と判定できる。 + +- **奇数桁**の場合: + - 例: `12321` + - 最後には `rev` の方が 1 桁多い(中央の桁を含む)状態で `x < rev` となりループを抜ける。 + - このとき、`rev // 10` を取ると中央の 1 桁が削除されるため、 + - `x == rev // 10` なら左右対称、 + - そうでなければ非対称と判断できる。 + +このため、ループ後の条件 + +```python +x == rev or x == rev // 10 +``` + +は、「元の数が回文である」ための必要十分条件になります。 + +### 4. 終了性 + +- 毎回 `x //= 10` により `x` は桁数が 1 つずつ減少していく。 +- `x` は有限桁数なので、必ず有限回の反復で `x <= rev` となりループを抜ける。 +- したがってアルゴリズムは必ず終了します。 + +--- + +

計算量

+ +- 入力整数 `x` の桁数を `d` とする。 + +### 時間計算量 + +- 各ループ反復で、`x` の桁数を 1 つ削減していく。 +- 最大でも `d` 回程度の反復でループが終了する。 +- 各反復内の処理は定数時間(数回の算術演算と比較)のみ。 + +**時間計算量:** + +- `O(d)` (≒ `O(log10 |x|)`) + +### 空間計算量 + +- 使用している追加の変数は + - `rev`(反転した右半分) + - `digit`(一時的な 1 桁) + - `x`(破壊的に更新) + +- いずれも `int` であり、配列や辞書などの追加データ構造は使用していない。 + +**空間計算量:** + +- 追加メモリは定数個の整数 → `O(1)` + +--- + +

Python 実装

+ +以下は、LeetCode の Python 環境(CPython 3.11+)で動作する、`class Solution` 形式の実装です。 +pylance で型エラーが出ないように、引数・戻り値には明示的に型注釈を付けています。 + +```python +from __future__ import annotations + + +class Solution: + def isPalindrome(self, x: int) -> bool: + """ + 整数 x が 10 進表記で回文かどうかを判定する。 + + Args: + x: 判定対象の整数 + + Returns: + x が回文であれば True、そうでなければ False。 + """ + # 1. 負数、0 以外で末尾が 0 の数は回文にならない + # 例: -121, 10, 100 など + if x < 0 or (x % 10 == 0 and x != 0): + return False + + # 2. 0〜9 の 1 桁の整数は必ず回文 + if x < 10: + return True + + # 3. 右半分の桁を反転して作る整数 rev + rev: int = 0 + + # 4. x が rev 以下になるまで、末尾の桁を移動し続ける + # - 偶数桁: 最終的に x と rev は同じ桁数になる + # - 奇数桁: rev の方が 1 桁多くなる(中央の桁を含む) + while x > rev: + # x の末尾 1 桁を取り出して rev に追加 + rev = rev * 10 + (x % 10) + # x から末尾 1 桁を削除 + x //= 10 + + # 5. 偶数桁: x == rev であれば回文 + # 奇数桁: rev の中央 1 桁を無視するため rev // 10 と比較 + return x == rev or x == rev // 10 +``` + +- この実装は問題文の制約(32bit 整数)に依存せず、任意の Python `int` に対しても正しく動作します(Python `int` は任意精度のため)。 +- LeetCode 上ではこの `Solution.isPalindrome` だけが呼び出され、外部状態には依存しない **純粋関数的な実装**です。 + +--- + +

CPython 最適化ポイント

+ +この問題はシンプルですが、CPython 3.11+ での挙動を踏まえた細かな最適化ポイントも押さえておきます。 + +1. **整数演算のみを使用** - `str()` で文字列に変換してからスライスで比較する方法もありますが、- 文字列オブジェクトの作成 - スライスによる新しい文字列の生成 + と、余分なオブジェクトが増えます。- 今回の実装は、C 実装の `int` 演算(`%`, `//`, `*`, `+`)だけを使うため、オブジェクト生成を最小限にできます。 + +2. **ループ内で関数呼び出しを行わない** + - `while` ループの本体は、すべてローカル変数へのアクセスと算術演算のみ。 + - 属性アクセス・関数呼び出しをループ外に追い出しているので、バイトコードレベルでのオーバーヘッドが小さいです。 + +3. **追加データ構造を持たない** + - `list`, `deque`, `dict`, `set` などを使わないため、GC による負荷もほぼありません。 + - メモリ局所性もよく、CPU キャッシュにも優しい構造です。 + +4. **条件分岐の位置** + - 高頻度でヒットする可能性のある条件(負数・末尾 0・1 桁)をループの前に寄せることで、ループに入るケースを削減しています。 + +--- + +

エッジケースと検証観点

+ +主なエッジケースと、それぞれで期待される挙動を整理します。 + +1. **負数** + - 例: `x = -1`, `x = -121`, `x = -10` + - 期待結果: すべて `False` + - 理由: 10 進表記で `-` が付くため必ず非回文。 + +2. **0(ゼロ)** + - 例: `x = 0` + - 期待結果: `True` + - 理由: `"0"` は左右対称。 + +3. **1 桁の正の整数** + - 例: `x = 1..9` + - 期待結果: すべて `True` + - 理由: 1 桁は必ず回文。 + +4. **末尾が 0 の正の整数** + - 例: `x = 10`, `x = 100`, `x = 1010` + - 期待結果: すべて `False` + - 理由: 先頭に `0` を置く表記はしないため、左右対称になり得ない。 + +5. **典型的な回文** + - 例: `x = 121`, `x = 1221`, `x = 12321`, `x = 1001` + - 期待結果: すべて `True` + +6. **非回文の正の整数** + - 例: `x = 123`, `x = 1231`, `x = 1002` + - 期待結果: すべて `False` + +7. **制約の境界付近** + - 例: + - `x = 2**31 - 1 = 2147483647` + - `x = -2**31 = -2147483648` + + - 期待: + - 正側: 回文でなければ `False` + - 負側: 負数なので `False` + + - Python `int` は任意精度なのでオーバーフローの心配はないが、LeetCode の制約範囲として確認。 + +これらのケースを手計算で追うことで、実装が期待どおりに動いているか、境界条件を誤っていないかを確認できます。 + +--- + +

FAQ

+ +**Q1. 文字列に変換して `s == s[::-1]` ではダメなの?** + +- アルゴリズムとしてはそれでも正しく解けますし、Python ではかなり簡潔で高速です。 +- ただし、この問題には「文字列に変換せずに解けるか?」という Follow up が付いているため、 + - **低レイヤの数値アルゴリズムを設計できるか** + - **余分なメモリを使わずに O(1) 空間で解けるか** + が評価ポイントになります。 + +- 本実装はその Follow up を満たす形になっています。 + +--- + +**Q2. どうして「数値全体を反転」ではなく「半分だけ反転」するの?** + +- 全体を反転して `rev == x` を確かめる方法でも解けますが、 + - 反転の途中でオーバーフローする可能性がある言語(C++ / Java 等)では追加のチェックが必要になります。 + +- 半分だけ反転する方法は、 + - 途中で値が必要以上に大きくなりにくい + - 奇数桁と偶数桁を一貫して処理できる + といった利点があります。 + +- Python では任意精度整数なので overflow は問題になりませんが、**他言語でもそのまま通用する堅牢な設計**という意味でもこの方法が好まれます。 + +--- + +**Q3. 関数の中で引数 `x` を書き換えているけれど、これは問題ないの?** + +- Python では整数 `int` はイミュータブルですが、**変数 `x` が指す値を更新しているだけ**なので問題ありません。 +- 外部から渡されたオブジェクト(リストや辞書など)を破壊的に変更しているわけではなく、 + - 引数 `x` のスコープは関数内部に閉じています。 + +- この問題の仕様では、関数の外側から `x` の元の値にアクセスすることはないため、**純粋関数的な意味での「副作用」はありません。** + +--- + +以上が、LeetCode 9「Palindrome Number」の Python / CPython 3.11+ 向け解説と実装です。数値だけで回文判定を行うパターンは、他の「桁ごとの処理」問題にも応用しやすいので、仕組みごと理解しておくと再利用性が高まります。 diff --git a/README.md b/README.md index adbec41e..27e67600 100644 --- a/README.md +++ b/README.md @@ -35,27 +35,27 @@ ```mermaid graph TB Root[Algorithm-DataStructures-Math-SQL Repository] - + Root --> Algo[Algorithm
アルゴリズム] Root --> DS[DataStructures
データ構造] Root --> Math[Mathematics
数学] Root --> SQL[SQL] - + Algo --> BS[Binary Search
二分探索] Algo --> DP[Dynamic Programming
動的計画法] Algo --> Greedy[Greedy
貪欲法] - + DS --> LL[LinkedList
連結リスト] DS --> Trees[Trees
木構造] DS --> Graphs[Graphs
グラフ] - + Math --> FSM[FSM
有限状態機械] Math --> Geo[Geometry
幾何学] Math --> NT[Number Theory
数論] - + SQL --> LC[LeetCode] SQL --> HR[HackerRank] - + style Root fill:#4A90E2,color:#fff style Algo fill:#7ED321,color:#fff style DS fill:#F5A623,color:#fff @@ -64,6 +64,7 @@ graph TB ``` **出典:** + - README.md 31-62 - README.md 75-100 @@ -82,25 +83,25 @@ graph LR A2[Dynamic Programming
動的計画法] A3[Two Pointers
2ポインタ] end - + subgraph DataStructures D1[LinkedList
連結リスト] D2[Trees
木構造] D3[In-place Operations
インプレース操作] end - + subgraph Mathematics M1[FSM
有限状態機械] M2[Geometry
幾何学] M3[Transformations
変換] end - + subgraph SQL S1[JOIN Patterns
結合パターン] S2[Window Functions
ウィンドウ関数] S3[Aggregation
集約] end - + style Algorithm fill:#7ED321,color:#fff style DataStructures fill:#F5A623,color:#fff style Mathematics fill:#BD10E0,color:#fff @@ -109,12 +110,12 @@ graph LR ### 領域分類テーブル -| 領域 | 主要コードエンティティ | コアパターン | 主要ディレクトリ | -|------|----------------------|--------------|------------------| -| **Algorithm**
アルゴリズム | `Solution.findMedianSortedArrays()`
`numDecodings()`
`minPathSum()` | 二分探索
動的計画法
2ポインタ | `Algorithm/BinarySearch/`
`Algorithm/DynamicProgramming/` | -| **DataStructures**
データ構造 | `Solution.addTwoNumbers()`
`ListNode`
`DoublyLinkedList` | In-place操作
ポインタ操作 | `DataStructures/LinkedList/`
`DataStructures/Trees/` | -| **Mathematics**
数学 | `isNumber()`
`reflectPoint()`
`gameWithCells()` | 有限状態機械
幾何変換 | `Mathematics/FSM/`
`Mathematics/Geometry/` | -| **SQL** | `CombineTwoTables.sql`
`RisingTemperature.sql`
`combine_two_tables()` (pandas) | JOINパターン
ウィンドウ関数 | `SQL/Leetcode/`
`SQL/HackerRank/` | +| 領域 | 主要コードエンティティ | コアパターン | 主要ディレクトリ | +| --------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------- | ------------------------------------------------------------- | +| **Algorithm**
アルゴリズム | `Solution.findMedianSortedArrays()`
`numDecodings()`
`minPathSum()` | 二分探索
動的計画法
2ポインタ | `Algorithm/BinarySearch/`
`Algorithm/DynamicProgramming/` | +| **DataStructures**
データ構造 | `Solution.addTwoNumbers()`
`ListNode`
`DoublyLinkedList` | In-place操作
ポインタ操作 | `DataStructures/LinkedList/`
`DataStructures/Trees/` | +| **Mathematics**
数学 | `isNumber()`
`reflectPoint()`
`gameWithCells()` | 有限状態機械
幾何変換 | `Mathematics/FSM/`
`Mathematics/Geometry/` | +| **SQL** | `CombineTwoTables.sql`
`RisingTemperature.sql`
`combine_two_tables()` (pandas) | JOINパターン
ウィンドウ関数 | `SQL/Leetcode/`
`SQL/HackerRank/` | **出典:** README.md 64-72 @@ -133,42 +134,42 @@ graph LR ```mermaid graph TB Problem[単一問題
Single Problem] - + Problem --> Claude[Claude実装
競技プログラミングアプローチ] Problem --> GPT[GPT実装
本番環境アプローチ] - + Claude --> CP[Python] Claude --> CT[TypeScript] Claude --> CJ[JavaScript] - + GPT --> GP[Python] GPT --> GT[TypeScript] GPT --> GJ[JavaScript] - + CP --> CT1[📄 Tier 1: README.md] CP --> CT2[🌐 Tier 2: README.html] CP --> CT3[⚛️ Tier 3: README_react.html] - + CT --> CTT1[📄 Tier 1: README.md] CT --> CTT2[🌐 Tier 2: README.html] CT --> CTT3[⚛️ Tier 3: README_react.html] - + CJ --> CJT1[📄 Tier 1: README.md] CJ --> CJT2[🌐 Tier 2: README.html] CJ --> CJT3[⚛️ Tier 3: README_react.html] - + GP --> GT1[📄 Tier 1: README.md] GP --> GT2[🌐 Tier 2: README.html] GP --> GT3[⚛️ Tier 3: README_react.html] - + GT --> GTT1[📄 Tier 1: README.md] GT --> GTT2[🌐 Tier 2: README.html] GT --> GTT3[⚛️ Tier 3: README_react.html] - + GJ --> GJT1[📄 Tier 1: README.md] GJ --> GJT2[🌐 Tier 2: README.html] GJ --> GJT3[⚛️ Tier 3: README_react.html] - + style Problem fill:#4A90E2,color:#fff style Claude fill:#7ED321,color:#fff style GPT fill:#F5A623,color:#fff @@ -176,25 +177,25 @@ graph TB ### 実装マトリックス構造テーブル -| 次元 | オプション | アーティファクト数 | 目的 | -|------|-----------|------------------|------| -| **AIプロバイダー** | Claude、GPT | 2 | 競技プログラミングと本番環境アプローチの比較 | -| **言語** | Python (.py)
TypeScript (.ts)
JavaScript (.js) | 3 | マルチ言語実装パターン | -| **ドキュメント** | README.md
README.html
README_react.html | 3 | プログレッシブ学習の複雑性 | -| **合計** | 2 × 3 × 3 | **18** | 問題ごとの完全な学習エコシステム | +| 次元 | オプション | アーティファクト数 | 目的 | +| ------------------ | ------------------------------------------------------ | ------------------ | -------------------------------------------- | +| **AIプロバイダー** | Claude、GPT | 2 | 競技プログラミングと本番環境アプローチの比較 | +| **言語** | Python (.py)
TypeScript (.ts)
JavaScript (.js) | 3 | マルチ言語実装パターン | +| **ドキュメント** | README.md
README.html
README_react.html | 3 | プログレッシブ学習の複雑性 | +| **合計** | 2 × 3 × 3 | **18** | 問題ごとの完全な学習エコシステム | ### 実装マトリックス全体像テーブル -| AI/言語 | Python | TypeScript | JavaScript | -|---------|--------|------------|------------| -| **Claude実装** | | | | -| 📄 Tier 1 | ✅ .py + README.md | ✅ .ts + README.md | ✅ .js + README.md | -| 🌐 Tier 2 | ✅ README.html | ✅ README.html | ✅ README.html | -| ⚛️ Tier 3 | ✅ README_react.html | ✅ README_react.html | ✅ README_react.html | -| **GPT実装** | | | | -| 📄 Tier 1 | ✅ .py + README.md | ✅ .ts + README.md | ✅ .js + README.md | -| 🌐 Tier 2 | ✅ README.html | ✅ README.html | ✅ README.html | -| ⚛️ Tier 3 | ✅ README_react.html | ✅ README_react.html | ✅ README_react.html | +| AI/言語 | Python | TypeScript | JavaScript | +| -------------- | -------------------- | -------------------- | -------------------- | +| **Claude実装** | | | | +| 📄 Tier 1 | ✅ .py + README.md | ✅ .ts + README.md | ✅ .js + README.md | +| 🌐 Tier 2 | ✅ README.html | ✅ README.html | ✅ README.html | +| ⚛️ Tier 3 | ✅ README_react.html | ✅ README_react.html | ✅ README_react.html | +| **GPT実装** | | | | +| 📄 Tier 1 | ✅ .py + README.md | ✅ .ts + README.md | ✅ .js + README.md | +| 🌐 Tier 2 | ✅ README.html | ✅ README.html | ✅ README.html | +| ⚛️ Tier 3 | ✅ README_react.html | ✅ README_react.html | ✅ README_react.html | **合計: 2 AI × 3 言語 × 3 階層 = 18 成果物/問題** @@ -214,33 +215,33 @@ graph TB ```mermaid graph LR Problem[問題
Problem] - + Problem --> Claude[Claude実装] Problem --> GPT[GPT実装] - + subgraph Claude_Approach[Claude アプローチ - 競技プログラミング] C1[⚡ 速度最適化] C2[🔢 整数センチネル] C3[✂️ 最小限の検証] C4[🎯 制約を信頼] C5[🏆 コンテスト向け] - + C1 --> C2 --> C3 --> C4 --> C5 end - + subgraph GPT_Approach[GPT アプローチ - 本番コード] G1[🛡️ 包括的検証] G2[🔍 型ガード] G3[⚠️ エラー処理] G4[📊 浮動小数点sentinel] G5[🏢 エンタープライズ向け] - + G1 --> G2 --> G3 --> G4 --> G5 end - + Claude --> Claude_Approach GPT --> GPT_Approach - + style Problem fill:#4A90E2,color:#fff style Claude fill:#7ED321,color:#fff style GPT fill:#F5A623,color:#fff @@ -250,16 +251,16 @@ graph LR ### 哲学比較詳細テーブル -| 側面 | Claude実装 | GPT実装 | -|------|-----------|---------| -| **Pythonメソッド
シグネチャ** | `findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float` | `_median_binary_partition(self, nums1: List[int], nums2: List[int]) -> float` | -| **センチネル値** | 整数: `NEG = -10_000_007`
`POS = +10_000_007` | 浮動小数点: `float("inf")`
`-float("inf")` | -| **TypeScript
シグネチャ** | `function findMedianSortedArrays(nums1: number[], nums2: number[]): number` | `function findMedianSortedArrays(nums1: readonly number[], nums2: readonly number[]): number` | -| **最適化の焦点** | ⚡ 整数センチネルによる速度最適化
(浮動小数点キャストを回避) | 🛡️ TypeError/RangeErrorを用いた
包括的入力検証 | -| **ドキュメント
スタイル** | 📈 最適化セクション付き計算量解析 | 📊 ビジネスコンテキストを含む
アルゴリズム比較表 | -| **検証戦略** | ✂️ 問題の制約を信頼し、最小限の検証 | 🔍 カスタム例外を用いた
広範なランタイム検証 | -| **パフォーマンス** | 🏆 10-15% 高速 | 🛡️ 5-10% 低速(検証オーバーヘッド) | -| **使用ケース** | 🎯 LeetCode/Codeforces
アルゴリズムコンテスト | 🏢 本番API
エンタープライズシステム | +| 側面 | Claude実装 | GPT実装 | +| --------------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | +| **Pythonメソッド
シグネチャ** | `findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float` | `_median_binary_partition(self, nums1: List[int], nums2: List[int]) -> float` | +| **センチネル値** | 整数: `NEG = -10_000_007`
`POS = +10_000_007` | 浮動小数点: `float("inf")`
`-float("inf")` | +| **TypeScript
シグネチャ** | `function findMedianSortedArrays(nums1: number[], nums2: number[]): number` | `function findMedianSortedArrays(nums1: readonly number[], nums2: readonly number[]): number` | +| **最適化の焦点** | ⚡ 整数センチネルによる速度最適化
(浮動小数点キャストを回避) | 🛡️ TypeError/RangeErrorを用いた
包括的入力検証 | +| **ドキュメント
スタイル** | 📈 最適化セクション付き計算量解析 | 📊 ビジネスコンテキストを含む
アルゴリズム比較表 | +| **検証戦略** | ✂️ 問題の制約を信頼し、最小限の検証 | 🔍 カスタム例外を用いた
広範なランタイム検証 | +| **パフォーマンス** | 🏆 10-15% 高速 | 🛡️ 5-10% 低速(検証オーバーヘッド) | +| **使用ケース** | 🎯 LeetCode/Codeforces
アルゴリズムコンテスト | 🏢 本番API
エンタープライズシステム | ### コードエンティティの例 @@ -282,10 +283,7 @@ class Solution: // Algorithm/BinarySearch/leetcode/4. Median of Two Sorted Arrays/GPT/ // Median_of_Two_Sorted_Arrays.ts -function findMedianSortedArrays( - nums1: readonly number[], - nums2: readonly number[] -): number { +function findMedianSortedArrays(nums1: readonly number[], nums2: readonly number[]): number { // readonly で不変性を保証 validateNumberArray(nums1); validateNumberArray(nums2); @@ -309,6 +307,7 @@ function findMedianSortedArrays(nums1, nums2) { ``` **出典:** + - README.md 102-142 - README.md 274-302 @@ -325,19 +324,19 @@ function findMedianSortedArrays(nums1, nums2) { ```mermaid graph TD Root[Algorithm-DataStructures-Math-SQL] - + Root --> Domain1[Algorithm] Root --> Domain2[DataStructures] Root --> Domain3[Mathematics] Root --> Domain4[SQL] - + Domain1 --> Topic[BinarySearch] Topic --> Platform[leetcode] Platform --> Problem[4. Median of Two Sorted Arrays] - + Problem --> AI1[Claude/] Problem --> AI2[GPT/] - + AI1 --> Files1[実装ファイル群] Files1 --> PY1[📝 .py
Python実装] Files1 --> TS1[📘 .ts
TypeScript実装] @@ -345,7 +344,7 @@ graph TD Files1 --> MD1[📄 README.md
静的ドキュメント] Files1 --> HTML1[🌐 README.html
インタラクティブHTML] Files1 --> REACT1[⚛️ README_react.html
Reactビジュアライゼーション] - + AI2 --> Files2[実装ファイル群] Files2 --> PY2[📝 .py
Python実装] Files2 --> TS2[📘 .ts
TypeScript実装] @@ -353,7 +352,7 @@ graph TD Files2 --> MD2[📄 README.md
静的ドキュメント] Files2 --> HTML2[🌐 README.html
インタラクティブHTML] Files2 --> REACT2[⚛️ README_react.html
Reactビジュアライゼーション] - + style Root fill:#4A90E2,color:#fff style Domain1 fill:#7ED321,color:#fff style AI1 fill:#F5A623,color:#fff @@ -362,14 +361,14 @@ graph TD ### ファイル命名パターンテーブル -| ファイルタイプ | 命名パターン | 目的 | 例 | -|--------------|-------------|------|-----| -| **Python実装** | `{ProblemName}.py`
`{problem_name}.py` | `class Solution`を含む
コア実装 | `Median_of_Two_Sorted_Arrays.py` | -| **TypeScript実装** | `{ProblemName}.ts` | 厳密なチェックを伴う
型安全な実装 | `Median_of_Two_Sorted_Arrays.ts` | -| **JavaScript実装** | `{ProblemName}.js` | ランタイム検証実装 | `Median_of_Two_Sorted_Arrays.js` | -| **静的ドキュメント** | `README.md` | 5セクション構造の
ドキュメント | セクションごとに<100行 | -| **インタラクティブHTML** | `README.html` | Prism.jsシンタックス
ハイライト、Tailwind CSS | 1000-2000行 | -| **Reactビジュアライゼーション** | `README_react.html` | React 18 + Babel Standalone
インタラクティブデモ | カスタマイズ可能な入力 | +| ファイルタイプ | 命名パターン | 目的 | 例 | +| ------------------------------- | ------------------------------------------ | ---------------------------------------------------- | -------------------------------- | +| **Python実装** | `{ProblemName}.py`
`{problem_name}.py` | `class Solution`を含む
コア実装 | `Median_of_Two_Sorted_Arrays.py` | +| **TypeScript実装** | `{ProblemName}.ts` | 厳密なチェックを伴う
型安全な実装 | `Median_of_Two_Sorted_Arrays.ts` | +| **JavaScript実装** | `{ProblemName}.js` | ランタイム検証実装 | `Median_of_Two_Sorted_Arrays.js` | +| **静的ドキュメント** | `README.md` | 5セクション構造の
ドキュメント | セクションごとに<100行 | +| **インタラクティブHTML** | `README.html` | Prism.jsシンタックス
ハイライト、Tailwind CSS | 1000-2000行 | +| **Reactビジュアライゼーション** | `README_react.html` | React 18 + Babel Standalone
インタラクティブデモ | カスタマイズ可能な入力 | ### 標準ディレクトリ構造の例 @@ -416,30 +415,30 @@ SQL/Leetcode/Basic join/175. Combine Two Tables/ ```mermaid graph TD Start[学習者エントリーポイント] --> Assess{スキルレベル評価} - + Assess -->|初心者
CS初心者| Beginner[Tier 1: README.md] Assess -->|中級者
競技プログラミング参加者| Inter[Tier 2: README.html] Assess -->|上級者
ソフトウェアエンジニア| Adv[Tier 3: README_react.html] - + Beginner --> L1[📖 基本概念理解] Inter --> L2[🎮 実行フロー理解] Adv --> L3[⚡ パフォーマンス分析] - + L1 --> CA1[📊 計算量解析
O記法の理解] L2 --> SV[👁️ 状態可視化
ステップ実行] L3 --> AI[🤖 AI比較研究
Claude vs GPT] - + CA1 --> IP[💡 実装パターン学習] SV --> EC[🔍 エッジケース検証] AI --> OPT[🚀 最適化戦略] - + IP --> Next{次のステップ} EC --> Next OPT --> Next - + Next -->|横展開| NextProblem[次の問題へ] Next -->|縦展開| NextTier[次の階層へ] - + style Start fill:#4A90E2,color:#fff style Beginner fill:#7ED321,color:#fff style Inter fill:#F5A623,color:#fff @@ -449,11 +448,11 @@ graph TD ### 階層比較詳細テーブル -| 階層 | ファイル | 対象読者 | 主要技術 | 主な特徴 | -|------|---------|---------|---------|---------| -| **Tier 1**
📄 静的 | `README.md` | 初心者
CS初心者 | Markdown | • 問題概要
• アルゴリズム説明
• 計算量解析 (O(n))
• 実装詳細
• 最適化の議論 | -| **Tier 2**
🌐 インタラクティブ | `README.html` | 中級者
競技プログラミング
参加者 | Prism.js
Tailwind CSS | • シンタックスハイライト
• ステップ制御システム
(play/pause/prev/next/reset)
• 状態の可視化
• SVGフローチャートレンダリング | -| **Tier 3**
⚛️ 動的 | `README_react.html` | 上級者
ソフトウェア
エンジニア | React 18
Babel Standalone | • Reactフック
• リアルタイム入力変更
• エッジケーステスト
• AI実装比較 (Claude vs GPT)
• パフォーマンスベンチマーク | +| 階層 | ファイル | 対象読者 | 主要技術 | 主な特徴 | +| ---------------------------------- | ------------------- | ---------------------------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| **Tier 1**
📄 静的 | `README.md` | 初心者
CS初心者 | Markdown | • 問題概要
• アルゴリズム説明
• 計算量解析 (O(n))
• 実装詳細
• 最適化の議論 | +| **Tier 2**
🌐 インタラクティブ | `README.html` | 中級者
競技プログラミング
参加者 | Prism.js
Tailwind CSS | • シンタックスハイライト
• ステップ制御システム
(play/pause/prev/next/reset)
• 状態の可視化
• SVGフローチャートレンダリング | +| **Tier 3**
⚛️ 動的 | `README_react.html` | 上級者
ソフトウェア
エンジニア | React 18
Babel Standalone | • Reactフック
• リアルタイム入力変更
• エッジケーステスト
• AI実装比較 (Claude vs GPT)
• パフォーマンスベンチマーク | ### Tier 1: 静的ドキュメント構造 (README.md) @@ -462,29 +461,29 @@ graph TD #### 📋 5セクション構造 1. **問題概要 (Problem Overview)** - - LeetCode/HackerRank問題の説明 - - 制約条件 (例: `1 ≤ n ≤ 10^5`) - - 入出力例 (3-5個) + - LeetCode/HackerRank問題の説明 + - 制約条件 (例: `1 ≤ n ≤ 10^5`) + - 入出力例 (3-5個) 2. **アルゴリズム説明 (Algorithm Explanation)** - - 詳細な解法アプローチと戦略 - - 直感的な説明 - - ステップバイステップガイド + - 詳細な解法アプローチと戦略 + - 直感的な説明 + - ステップバイステップガイド 3. **計算量解析 (Complexity Analysis)** - - 時間計算量: O(...)の詳細な導出 - - 空間計算量: O(...)の詳細な導出 - - 最悪ケース・平均ケース・最良ケース分析 + - 時間計算量: O(...)の詳細な導出 + - 空間計算量: O(...)の詳細な導出 + - 最悪ケース・平均ケース・最良ケース分析 4. **実装詳細 (Implementation Details)** - - 重要なロジックを強調したコアコードのウォークスルー - - 行ごとの詳細な解説 - - エッジケースの処理方法 + - 重要なロジックを強調したコアコードのウォークスルー + - 行ごとの詳細な解説 + - エッジケースの処理方法 5. **最適化の議論 (Optimization Discussion)** - - 言語固有の最適化技術とトレードオフ - - 代替アプローチとの比較 - - パフォーマンスチューニング戦略 + - 言語固有の最適化技術とトレードオフ + - 代替アプローチとの比較 + - パフォーマンスチューニング戦略 #### 📊 特徴 @@ -506,17 +505,17 @@ graph LR HTML --> Steps[ステップ制御システム] HTML --> State[状態可視化] HTML --> Flow[SVGフローチャート] - + Steps --> Play[▶▶ Play] Steps --> Pause[⏸ Pause] Steps --> Prev[◀ Previous] Steps --> Next[▶ Next] Steps --> Reset[⟲ Reset] - + State --> Vars[変数値表示] State --> Stack[スタック状態] State --> Array[配列の変化] - + style HTML fill:#4A90E2,color:#fff style Prism fill:#7ED321,color:#fff style Tailwind fill:#06B6D4,color:#fff @@ -547,24 +546,24 @@ Reactを使用した高度なインタラクティブ機能: graph TD Root[README_react.html] --> React[React 18] Root --> Babel[Babel Standalone
JSX変換] - + React --> Hooks[React Hooks] React --> Components[コンポーネント群] - + Hooks --> State[useState
状態管理] Hooks --> Effect[useEffect
副作用処理] Hooks --> Memo[useMemo
メモ化] - + Components --> Input[InputController
リアルタイム入力] Components --> Comp[AIComparator
Claude vs GPT比較] Components --> Bench[PerformanceBenchmark
ベンチマーク] Components --> Edge[EdgeCaseTester
エッジケーステスト] - + Input --> Real[即座に結果反映] Comp --> Side[サイドバイサイド表示] Bench --> Time[実行時間測定] Edge --> Auto[自動テスト実行] - + style Root fill:#4A90E2,color:#fff style React fill:#61DAFB,color:#000 style Babel fill:#F5DA55,color:#000 @@ -575,31 +574,31 @@ graph TD #### 🚀 高度な機能 1. **React 18関数コンポーネント** - - モダンなReactフックによる状態管理 - - `useState`, `useEffect`, `useMemo`の活用 + - モダンなReactフックによる状態管理 + - `useState`, `useEffect`, `useMemo`の活用 2. **Babel Standalone** - - ビルドツールなしのブラウザベースJSX変換 - - 即座に実行可能な環境 + - ビルドツールなしのブラウザベースJSX変換 + - 即座に実行可能な環境 3. **リアルタイム入力変更** - - ユーザーがテスト入力を変更 - - 即座に結果を確認可能 - - インタラクティブなデバッグ体験 + - ユーザーがテスト入力を変更 + - 即座に結果を確認可能 + - インタラクティブなデバッグ体験 4. **エッジケーステスト** - - ワンクリックテスト用の事前設定されたエッジケース - - 空配列、単一要素、負の数、大きな数値など + - ワンクリックテスト用の事前設定されたエッジケース + - 空配列、単一要素、負の数、大きな数値など 5. **AI実装比較** - - ClaudeとGPTのアプローチの並列比較 - - 実装の違いを視覚的に理解 - - パフォーマンス特性の比較 + - ClaudeとGPTのアプローチの並列比較 + - 実装の違いを視覚的に理解 + - パフォーマンス特性の比較 6. **パフォーマンスベンチマーク** - - 最適化検証のためのオプションのタイミング測定 - - 実行時間の可視化 - - メモリ使用量の追跡 + - 最適化検証のためのオプションのタイミング測定 + - 実行時間の可視化 + - メモリ使用量の追跡 #### 📊 特徴 @@ -629,26 +628,26 @@ graph TB ESLint["ESLint ^9.37.0
コード品質検証"] LiveServer[live-server ^1.2.2
開発サーバー] end - + subgraph Docs[ドキュメントレイヤー] Prism[Prism.js
シンタックスハイライト] Tailwind[Tailwind CSS
モダンスタイリング] React[React 18
インタラクティブUI] Babel[Babel Standalone
JSX変換] end - + Core --> Docs - + Python --> Algo[Algorithm実装
標準ライブラリのみ] Node1 --> JS[JavaScript実装] Node2 --> TSImpl[TypeScript実装] Bun --> Lock[deterministic builds
Lockfile v1] - + Prism --> Tier2[Tier 2: README.html] Tailwind --> Tier2 React --> Tier3[Tier 3: README_react.html] Babel --> Tier3 - + style Core fill:#E3F2FD style Docs fill:#FFF3E0 style Python fill:#3776AB,color:#fff @@ -660,14 +659,14 @@ graph TB ### コア開発環境テーブル -| コンポーネント | バージョン/設定 | 目的 | -|--------------|----------------|------| -| **Python** | CPython 3.11.10 | 型ヒント付きアルゴリズム実装 | -| **Node.js** | v18.x (JavaScript)
v22.14.0 (TypeScript) | TS/JS実装のランタイム環境 | -| **Bun** | Lockfileバージョン 1 | パッケージ管理と決定論的ビルド | -| **TypeScript** | @types/node ^22.18.10 | Node.js型定義 | -| **ESLint** | ^9.37.0 | コード品質検証とリンティング | -| **live-server** | ^1.2.2 | ライブリロード開発サーバー | +| コンポーネント | バージョン/設定 | 目的 | +| --------------- | -------------------------------------------- | ------------------------------ | +| **Python** | CPython 3.11.10 | 型ヒント付きアルゴリズム実装 | +| **Node.js** | v18.x (JavaScript)
v22.14.0 (TypeScript) | TS/JS実装のランタイム環境 | +| **Bun** | Lockfileバージョン 1 | パッケージ管理と決定論的ビルド | +| **TypeScript** | @types/node ^22.18.10 | Node.js型定義 | +| **ESLint** | ^9.37.0 | コード品質検証とリンティング | +| **live-server** | ^1.2.2 | ライブリロード開発サーバー | ### 外部ライブラリポリシー @@ -678,19 +677,19 @@ graph TB ```mermaid graph LR Allowed[許可されるライブラリ] - + Allowed --> PyStd[Python標準ライブラリ] Allowed --> JSStd[JS/TS標準ライブラリ] - + PyStd --> typing[typing
型ヒント] PyStd --> collections[collections
データ構造] PyStd --> itertools[itertools
イテレータ] PyStd --> math[math
数学関数] - + JSStd --> Array[Array methods
配列操作] JSStd --> Object[Object methods
オブジェクト操作] JSStd --> Math[Math object
数学関数] - + style Allowed fill:#7ED321,color:#fff style PyStd fill:#3776AB,color:#fff style JSStd fill:#F7DF1E,color:#000 @@ -698,20 +697,20 @@ graph LR #### ❌ 禁止されるライブラリ -| カテゴリ | 禁止ライブラリ | 理由 | -|---------|---------------|------| -| **Pythonサードパーティ** | `numpy`, `scipy`, `pandas` (アルゴリズム実装で) | 教育的透明性の欠如 | -| **JavaScriptサードパーティ** | `lodash`, `underscore`, `ramda` | 面接環境との不整合 | -| **理由** | - | 学習目的: 内部実装の理解
実践的: 面接でライブラリは使用不可 | +| カテゴリ | 禁止ライブラリ | 理由 | +| ---------------------------- | ----------------------------------------------- | --------------------------------------------------------------- | +| **Pythonサードパーティ** | `numpy`, `scipy`, `pandas` (アルゴリズム実装で) | 教育的透明性の欠如 | +| **JavaScriptサードパーティ** | `lodash`, `underscore`, `ramda` | 面接環境との不整合 | +| **理由** | - | 学習目的: 内部実装の理解
実践的: 面接でライブラリは使用不可 | #### 📚 ドキュメントレイヤーの例外 ドキュメント生成に限り、以下のライブラリを使用: -| 階層 | 使用ライブラリ | 目的 | -|------|---------------|------| -| **Tier 2**
README.html | • Prism.js
• Tailwind CSS | シンタックスハイライト
モダンスタイリング | -| **Tier 3**
README_react.html | • React 18
• Babel Standalone | インタラクティブUI
JSX変換 | +| 階層 | 使用ライブラリ | 目的 | +| -------------------------------- | --------------------------------- | --------------------------------------------- | +| **Tier 2**
README.html | • Prism.js
• Tailwind CSS | シンタックスハイライト
モダンスタイリング | +| **Tier 3**
README_react.html | • React 18
• Babel Standalone | インタラクティブUI
JSX変換 | ### ドキュメント品質管理 @@ -721,26 +720,23 @@ graph LR ```json { - "MD013": { - "line_length": 100, - "code_blocks": false, - "tables": false - }, - "MD033": { - "allowed_elements": [ - "h1", "h2", "details", "summary", - "p", "i", "footer", "div" - ] - } + "MD013": { + "line_length": 100, + "code_blocks": false, + "tables": false + }, + "MD033": { + "allowed_elements": ["h1", "h2", "details", "summary", "p", "i", "footer", "div"] + } } ``` #### 📋 ルール説明 -| ルール | 設定 | 目的 | -|--------|------|------| -| **MD013** | `line_length: 100`
(コードブロックとテーブルを除外) | 読みやすさの向上
エディタでの表示最適化 | -| **MD033** | 特定のHTMLタグを許可 | インタラクティブ要素のサポート
リッチなドキュメント表現 | +| ルール | 設定 | 目的 | +| --------- | ------------------------------------------------------- | ----------------------------------------------------------- | +| **MD013** | `line_length: 100`
(コードブロックとテーブルを除外) | 読みやすさの向上
エディタでの表示最適化 | +| **MD033** | 特定のHTMLタグを許可 | インタラクティブ要素のサポート
リッチなドキュメント表現 | **目的**: すべての静的ドキュメントファイル間の一貫性を確保 @@ -757,32 +753,32 @@ SQL問題は、MySQL、PostgreSQL、Pandas/Pythonのプラットフォーム固 ```mermaid graph TD SQLProblem[SQL問題
Combine Two Tables] - + SQLProblem --> MySQL[MySQL実装] SQLProblem --> Postgres[PostgreSQL実装] SQLProblem --> Pandas[Pandas実装] - + MySQL --> M1[LEFT JOIN
標準結合] MySQL --> M2[CREATE INDEX
パフォーマンス最適化] MySQL --> M3[DATE_SUB
日付関数] MySQL --> M4[小文字テーブル名] - + Postgres --> P1[DISTINCT ON
効率的重複排除] Postgres --> P2[LATERAL JOIN
相関サブクエリ] Postgres --> P3[LAG/LEAD/DENSE_RANK
ウィンドウ関数] Postgres --> P4[Covering Index
高度なインデックス] Postgres --> P5[大文字小文字識別子
quoted identifiers] - + Pandas --> PD1[DataFrame.merge
標準マージ] Pandas --> PD2[Series.map
最適化マッピング] Pandas --> PD3[get_indexer
カスタムインデックス] Pandas --> PD4[set_index
事前インデックス設定] - + M1 --> Perf1[実行時間: ~45ms
10万行] P1 --> Perf2[実行時間: ~38ms
10万行] PD1 --> Perf3[実行時間: ~120ms
10万行] PD2 --> Perf4[最適化後: ~65ms
10万行] - + style SQLProblem fill:#4A90E2,color:#fff style MySQL fill:#00758F,color:#fff style Postgres fill:#336791,color:#fff @@ -813,6 +809,7 @@ LEFT JOIN Address AS a ON a.personId = p.personId; ``` **MySQL特徴:** + - 小文字テーブル名 (`person`, `address`) - 標準的なLEFT JOIN構文 - `DATE_SUB()`, `DATE_ADD()`による日付操作 @@ -825,7 +822,7 @@ LEFT JOIN Address AS a ON a.personId = p.personId; -- CombineTwoTables_postgre.md -- DISTINCT ONによる効率的な重複排除 -SELECT DISTINCT ON (p.personId) +SELECT DISTINCT ON (p.personId) p.firstName, p.lastName, a.city, a.state FROM Person p LEFT JOIN Address a ON a.personId = p.personId @@ -835,7 +832,7 @@ ORDER BY p.personId, a.city; SELECT "firstName", "lastName" FROM "Person"; -- 高度なウィンドウ関数の使用例 -SELECT +SELECT firstName, lastName, city, @@ -846,6 +843,7 @@ LEFT JOIN Address a ON a.personId = p.personId; ``` **PostgreSQL特徴:** + - `DISTINCT ON`: PostgreSQL固有の重複排除 - `LATERAL JOIN`: 相関サブクエリの代替 - 完全なウィンドウ関数サポート: `LAG`, `LEAD`, `DENSE_RANK`, `ROW_NUMBER` @@ -866,8 +864,8 @@ def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFr 時間計算量: O(n + m) """ result = person.merge( - address[["personId", "city", "state"]], - on="personId", + address[["personId", "city", "state"]], + on="personId", how="left" ) return result[["firstName", "lastName", "city", "state"]] @@ -881,18 +879,19 @@ def combine_two_tables_optimized(person: pd.DataFrame, address: pd.DataFrame) -> """ # 1:1マッピングの場合、mapの方が高速 address_dict = address.set_index('personId')[['city', 'state']].to_dict('index') - + person['city'] = person['personId'].map( lambda x: address_dict.get(x, {}).get('city', None) ) person['state'] = person['personId'].map( lambda x: address_dict.get(x, {}).get('state', None) ) - + return person[["firstName", "lastName", "city", "state"]] ``` **Pandas特徴:** + - `DataFrame.merge()`: SQL JOIN相当 - `Series.map()`: 1:1マッピングでの最適化 - `get_indexer()`: カスタムインデックス操作 @@ -900,15 +899,15 @@ def combine_two_tables_optimized(person: pd.DataFrame, address: pd.DataFrame) -> ### プラットフォーム機能比較テーブル -| 機能 | MySQL | PostgreSQL | Pandas | -|------|-------|-----------|--------| -| **JOIN構文** | `LEFT JOIN` | `LEFT JOIN`
`LATERAL JOIN` | `DataFrame.merge(how="left")` | -| **重複排除** | `DISTINCT` | `DISTINCT ON (column)` | `drop_duplicates()` | -| **日付操作** | `DATE_SUB()`
`DATE_ADD()` | `INTERVAL '1 day'`
`LAG()`
`date_trunc()` | `pd.Timedelta()`
`shift()`
`dt.floor()` | -| **インデックス** | `CREATE INDEX` | Covering indexes
Partial indexes
`CREATE INDEX CONCURRENTLY` | `set_index()`
`get_indexer()`
`MultiIndex` | -| **ウィンドウ関数** | 限定的サポート
(MySQL 8.0+) | 完全サポート
`LAG`, `LEAD`
`DENSE_RANK`
`ROW_NUMBER` | `groupby().transform()`
`shift()`
`rolling()` | -| **識別子** | 大文字小文字非区別
(デフォルト) | 大文字小文字区別
(引用符付き) | 大文字小文字区別
(カラム名) | -| **実行時間**
(10万行) | ~45ms
(インデックスあり) | ~38ms
(Covering Index) | `merge()`: ~120ms
`Series.map()`: ~65ms | +| 機能 | MySQL | PostgreSQL | Pandas | +| ------------------------- | ----------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------- | +| **JOIN構文** | `LEFT JOIN` | `LEFT JOIN`
`LATERAL JOIN` | `DataFrame.merge(how="left")` | +| **重複排除** | `DISTINCT` | `DISTINCT ON (column)` | `drop_duplicates()` | +| **日付操作** | `DATE_SUB()`
`DATE_ADD()` | `INTERVAL '1 day'`
`LAG()`
`date_trunc()` | `pd.Timedelta()`
`shift()`
`dt.floor()` | +| **インデックス** | `CREATE INDEX` | Covering indexes
Partial indexes
`CREATE INDEX CONCURRENTLY` | `set_index()`
`get_indexer()`
`MultiIndex` | +| **ウィンドウ関数** | 限定的サポート
(MySQL 8.0+) | 完全サポート
`LAG`, `LEAD`
`DENSE_RANK`
`ROW_NUMBER` | `groupby().transform()`
`shift()`
`rolling()` | +| **識別子** | 大文字小文字非区別
(デフォルト) | 大文字小文字区別
(引用符付き) | 大文字小文字区別
(カラム名) | +| **実行時間**
(10万行) | ~45ms
(インデックスあり) | ~38ms
(Covering Index) | `merge()`: ~120ms
`Series.map()`: ~65ms | ### パフォーマンス比較チャート @@ -920,12 +919,12 @@ graph LR P3[Pandas
Series.map
~65ms] P4[Pandas
DataFrame.merge
~120ms] end - + P1 -.->|最速| Best[🏆 最適] P2 -.->|高速| Good[✅ 良好] P3 -.->|標準| OK[⚡ 標準] P4 -.->|低速| Slow[🐌 要最適化] - + style P1 fill:#7ED321,color:#fff style P2 fill:#7ED321,color:#fff style P3 fill:#F5A623,color:#fff @@ -945,21 +944,21 @@ graph LR ```mermaid graph TB Repo[Algorithm-DataStructures-Math-SQL
Repository] - + Repo --> U1[アルゴリズム学習者] Repo --> U2[競技プログラマー] Repo --> U3[就職活動者] Repo --> U4[エンジニア/研究者] Repo --> U5[教育者] Repo --> U6[ポリグロット開発者] - + U1 --> F1[包括的リファレンス
計算量解析
ステップバイステップ] U2 --> F2[最適化ソリューション
最小限の検証
Claude実装] U3 --> F3[実装パターン
ベストプラクティス
複数解法] U4 --> F4[言語固有最適化
パフォーマンス比較
GPT実装] U5 --> F5[3段階学習システム
プログレッシブ複雑性
視覚補助] U6 --> F6[Python/TS/JS統一API
言語間比較
マルチ言語実装] - + style Repo fill:#4A90E2,color:#fff style U1 fill:#7ED321,color:#fff style U2 fill:#F5A623,color:#fff @@ -971,46 +970,46 @@ graph TB ### 主要ユースケースマトリックステーブル -| ユースケース | ターゲットユーザー | 利用される主要機能 | 推奨階層 | -|------------|------------------|------------------|---------| -| **アルゴリズム学習** | CS学生
自学自習者 | • 包括的リファレンス
• 計算量解析
• ステップバイステップ
ビジュアライゼーション | Tier 1 → 2 | -| **競技プログラミング準備** | LeetCode/HackerRank
参加者 | • 最適化されたソリューション
• 最小限の検証
• Claude実装(速度優先)
• プラットフォーム固有アプローチ | Tier 1 + Claude | -| **技術面接準備** | 就職活動者
転職希望者 | • 実装パターン
• ベストプラクティス
• 複数の解法アプローチ
• エッジケース処理 | Tier 1 → 3
Claude + GPT | -| **パフォーマンス
最適化研究** | ソフトウェアエンジニア
研究者 | • 言語固有技術
• 並列実装比較
• ベンチマーク
• GPT実装(安全性優先) | Tier 3
GPT | -| **教育指導** | 講師
チューター
メンター | • 3段階学習システム
• プログレッシブ複雑性
• 視覚補助
• インタラクティブデモ | 全階層 | -| **マルチ言語
一貫性研究** | ポリグロット開発者
言語比較研究者 | • Python/TypeScript/JavaScript
統一API
• 言語間パフォーマンス比較 | 全言語
Tier 3 | +| ユースケース | ターゲットユーザー | 利用される主要機能 | 推奨階層 | +| --------------------------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------------------- | +| **アルゴリズム学習** | CS学生
自学自習者 | • 包括的リファレンス
• 計算量解析
• ステップバイステップ
ビジュアライゼーション | Tier 1 → 2 | +| **競技プログラミング準備** | LeetCode/HackerRank
参加者 | • 最適化されたソリューション
• 最小限の検証
• Claude実装(速度優先)
• プラットフォーム固有アプローチ | Tier 1 + Claude | +| **技術面接準備** | 就職活動者
転職希望者 | • 実装パターン
• ベストプラクティス
• 複数の解法アプローチ
• エッジケース処理 | Tier 1 → 3
Claude + GPT | +| **パフォーマンス
最適化研究** | ソフトウェアエンジニア
研究者 | • 言語固有技術
• 並列実装比較
• ベンチマーク
• GPT実装(安全性優先) | Tier 3
GPT | +| **教育指導** | 講師
チューター
メンター | • 3段階学習システム
• プログレッシブ複雑性
• 視覚補助
• インタラクティブデモ | 全階層 | +| **マルチ言語
一貫性研究** | ポリグロット開発者
言語比較研究者 | • Python/TypeScript/JavaScript
統一API
• 言語間パフォーマンス比較 | 全言語
Tier 3 | ### スキルレベル別学習パス ```mermaid graph TD Start[学習開始] --> Level{現在のスキルレベル} - + Level -->|初心者
Beginner| Path1[初心者パス] Level -->|中級者
Intermediate| Path2[中級者パス] Level -->|上級者
Advanced| Path3[上級者パス] - + Path1 --> B1[Tier 1静的ドキュメント
README.md] B1 --> B2[基本概念理解
アルゴリズムの直感] B2 --> B3[計算量解析
O記法の理解] B3 --> B4[実装パターン学習
コーディング練習] B4 --> Progress1[次のレベルへ] - + Path2 --> I1[Tier 2インタラクティブHTML
README.html] I1 --> I2[実行検証
ステップバイステップ] I2 --> I3[状態可視化
デバッグ技術] I3 --> I4[マルチ言語実装比較
Python/TS/JS] I4 --> Progress2[次のレベルへ] - + Path3 --> A1[Tier 3 Reactビジュアライゼーション
README_react.html] A1 --> A2[詳細分析
パフォーマンスプロファイリング] A2 --> A3[AI実装比較
Claude vs GPT] A3 --> A4[本番環境vs競技実装
トレードオフ理解] A4 --> Progress3[マスタリー達成] - + Progress1 -.->|成長| Path2 Progress2 -.->|成長| Path3 - + style Start fill:#4A90E2,color:#fff style Path1 fill:#7ED321,color:#fff style Path2 fill:#F5A623,color:#fff @@ -1019,11 +1018,11 @@ graph TD ### スキルレベル進行テーブル -| レベル | ターゲットユーザー | 推奨アプローチ | 学習期間 | 達成目標 | -|--------|------------------|---------------|---------|---------| -| **初心者**
Beginner | • CS初心者
• 競技プログラミング
初心者
• プログラミング
基礎学習者 | • Tier 1静的ドキュメントから開始
• 基本概念を理解
• 計算量解析の学習
• 簡単な問題から着手 | 1-2ヶ月 | アルゴリズムの
基本理解 | -| **中級者**
Intermediate | • 競技プログラミング
参加者
• 面接準備中
• CS専攻学生 | • Tier 2インタラクティブHTML
で実行検証
• マルチ言語実装を比較
• エッジケースの理解 | 2-4ヶ月 | 実装力と
デバッグ能力 | -| **上級者**
Advanced | • ソフトウェア
エンジニア
• 言語最適化研究者
• テックリード | • Tier 3 Reactビジュアライゼーション
で詳細分析
• 本番環境vs競技実装を検証
• パフォーマンスチューニング | 継続的 | 最適化戦略と
アーキテクチャ設計 | +| レベル | ターゲットユーザー | 推奨アプローチ | 学習期間 | 達成目標 | +| --------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------- | +| **初心者**
Beginner | • CS初心者
• 競技プログラミング
初心者
• プログラミング
基礎学習者 | • Tier 1静的ドキュメントから開始
• 基本概念を理解
• 計算量解析の学習
• 簡単な問題から着手 | 1-2ヶ月 | アルゴリズムの
基本理解 | +| **中級者**
Intermediate | • 競技プログラミング
参加者
• 面接準備中
• CS専攻学生 | • Tier 2インタラクティブHTML
で実行検証
• マルチ言語実装を比較
• エッジケースの理解 | 2-4ヶ月 | 実装力と
デバッグ能力 | +| **上級者**
Advanced | • ソフトウェア
エンジニア
• 言語最適化研究者
• テックリード | • Tier 3 Reactビジュアライゼーション
で詳細分析
• 本番環境vs競技実装を検証
• パフォーマンスチューニング | 継続的 | 最適化戦略と
アーキテクチャ設計 | **出典:** README.md 370-392 @@ -1039,18 +1038,18 @@ graph TD gantt title Algorithm-DataStructures-Math-SQL 完全学習ロードマップ dateFormat YYYY-MM-DD - + section Phase 1: 基礎固め (1-2ヶ月) Binary Search学習 :a1, 2025-01-01, 14d LinkedList学習 :a2, after a1, 14d Mathematics FSM学習 :a3, after a2, 14d SQL基礎 :a4, after a2, 14d - + section Phase 2: 実践力強化 (2-3ヶ月) 横断比較学習 :b1, after a4, 30d パターン認識 :b2, after b1, 30d パフォーマンス最適化 :b3, after b2, 30d - + section Phase 3: マスターレベル (継続的) 競技プログラミング参加 :c1, after b3, 90d 本番環境コード作成 :c2, after b3, 90d @@ -1062,73 +1061,73 @@ gantt ```mermaid graph TD Start[学習開始] --> Phase1[Phase 1: 基礎固め] - + Phase1 --> W12[Week 1-2: Binary Search] Phase1 --> W34[Week 3-4: LinkedList] Phase1 --> W58[Week 5-8: Math FSM + SQL] - + W12 --> W12_1[問題: Median of Two Sorted Arrays] W12_1 --> W12_2[Claude/README.md で基本理解] W12_2 --> W12_3[GPT/README.md で検証アプローチ比較] W12_3 --> W12_4[両方のPython実装を写経] - + W34 --> W34_1[問題: Add Two Numbers] W34_1 --> W34_2[Claude/README.html でポインタ操作可視化] W34_2 --> W34_3[GPT/README.htmlでエッジケース理解] W34_3 --> W34_4[TypeScript実装で型安全性学習] - + W58 --> W58_1[FSM: Valid Number] W58 --> W58_2[SQL: Combine Two Tables] W58_1 --> W58_3[状態遷移図の理解] W58_2 --> W58_4[MySQL/PostgreSQL/Pandas実装] - + W12_4 --> Phase2[Phase 2: 実践力強化] W34_4 --> Phase2 W58_3 --> Phase2 W58_4 --> Phase2 - + Phase2 --> M3[Month 3: 横断比較学習] Phase2 --> M4[Month 4: パターン認識] Phase2 --> M5[Month 5: パフォーマンス最適化] - + M3 --> M3_1[同一問題の全18成果物を比較] M3_1 --> M3_2[Claude Python vs GPT Python] M3_1 --> M3_3[Python vs TypeScript vs JavaScript] M3_1 --> M3_4[Tier 1 vs Tier 2 vs Tier 3] - + M4 --> M4_1[トピック別集中学習] M4_1 --> M4_2[DynamicProgramming: 10問] M4_1 --> M4_3[Trees: 8問] M4_1 --> M4_4[SQL Window Functions: 5問] - + M5 --> M5_1[README_react.htmlでベンチマーク] M5_1 --> M5_2[言語間パフォーマンス比較] M5_1 --> M5_3[AI実装の速度差分析] M5_1 --> M5_4[最適化技術の実験] - + M3_4 --> Phase3[Phase 3: マスターレベル] M4_4 --> Phase3 M5_4 --> Phase3 - + Phase3 --> Track1[競技プログラミング参加] Phase3 --> Track2[本番環境コード作成] Phase3 --> Track3[コントリビューション] - + Track1 --> Track1_1[Claude実装を競技で活用] Track1_1 --> Track1_2[LeetCode Contest] Track1_1 --> Track1_3[Codeforces] Track1_1 --> Track1_4[AtCoder] - + Track2 --> Track2_1[GPT実装をプロダクションに応用] Track2_1 --> Track2_2[APIライブラリ開発] Track2_1 --> Track2_3[エンタープライズシステム] Track2_1 --> Track2_4[テストカバレッジ向上] - + Track3 --> Track3_1[リポジトリへの貢献] Track3_1 --> Track3_2[新問題の追加] Track3_1 --> Track3_3[ドキュメント改善] Track3_1 --> Track3_4[バグ修正・最適化提案] - + style Start fill:#4A90E2,color:#fff style Phase1 fill:#7ED321,color:#fff style Phase2 fill:#F5A623,color:#fff @@ -1141,17 +1140,18 @@ graph TD **目標**: 二分探索の基本概念とO(log n)計算量の理解 -| 日 | 活動 | 使用リソース | 所要時間 | -|----|------|-------------|---------| -| 1-2 | 問題理解: Median of Two Sorted Arrays | Claude/README.md | 2時間 | -| 3-4 | アルゴリズム解説の精読 | GPT/README.md | 2時間 | -| 5-6 | Python実装の写経 (Claude版) | .py ファイル | 3時間 | -| 7-8 | Python実装の写経 (GPT版) | .py ファイル | 3時間 | -| 9-10 | 実装比較とデバッグ | README.html (Tier 2) | 2時間 | -| 11-12 | TypeScript実装の挑戦 | .ts ファイル | 3時間 | -| 13-14 | 復習とパフォーマンステスト | README_react.html (Tier 3) | 2時間 | +| 日 | 活動 | 使用リソース | 所要時間 | +| ----- | ------------------------------------- | -------------------------- | -------- | +| 1-2 | 問題理解: Median of Two Sorted Arrays | Claude/README.md | 2時間 | +| 3-4 | アルゴリズム解説の精読 | GPT/README.md | 2時間 | +| 5-6 | Python実装の写経 (Claude版) | .py ファイル | 3時間 | +| 7-8 | Python実装の写経 (GPT版) | .py ファイル | 3時間 | +| 9-10 | 実装比較とデバッグ | README.html (Tier 2) | 2時間 | +| 11-12 | TypeScript実装の挑戦 | .ts ファイル | 3時間 | +| 13-14 | 復習とパフォーマンステスト | README_react.html (Tier 3) | 2時間 | **達成目標**: + - ✅ 二分探索の原理理解 - ✅ O(log n)計算量の実感 - ✅ センチネル値の使い方 @@ -1161,17 +1161,18 @@ graph TD **目標**: ポインタ操作とIn-place操作の習得 -| 日 | 活動 | 使用リソース | 所要時間 | -|----|------|-------------|---------| -| 1-2 | 問題理解: Add Two Numbers | Claude/README.md | 2時間 | -| 3-4 | ポインタ操作の可視化 | README.html (Tier 2) | 2時間 | -| 5-6 | Python実装 (両AI比較) | Claude/.py + GPT/.py | 3時間 | -| 7-8 | TypeScript型安全実装 | .ts ファイル | 3時間 | -| 9-10 | エッジケーステスト | README_react.html | 2時間 | -| 11-12 | JavaScript動的型実装 | .js ファイル | 2時間 | -| 13-14 | 総合復習と応用問題 | 関連問題 | 3時間 | +| 日 | 活動 | 使用リソース | 所要時間 | +| ----- | ------------------------- | -------------------- | -------- | +| 1-2 | 問題理解: Add Two Numbers | Claude/README.md | 2時間 | +| 3-4 | ポインタ操作の可視化 | README.html (Tier 2) | 2時間 | +| 5-6 | Python実装 (両AI比較) | Claude/.py + GPT/.py | 3時間 | +| 7-8 | TypeScript型安全実装 | .ts ファイル | 3時間 | +| 9-10 | エッジケーステスト | README_react.html | 2時間 | +| 11-12 | JavaScript動的型実装 | .js ファイル | 2時間 | +| 13-14 | 総合復習と応用問題 | 関連問題 | 3時間 | **達成目標**: + - ✅ LinkedListの基本操作 - ✅ ポインタ操作の理解 - ✅ メモリ管理の意識 @@ -1181,14 +1182,15 @@ graph TD **目標**: 有限状態機械とSQL基礎の習得 -| Week | 活動 | 使用リソース | 達成目標 | -|------|------|-------------|---------| -| 5 | FSM: Valid Number | Mathematics/FSM/ | 状態遷移図の理解 | -| 6 | SQL: Combine Two Tables (MySQL) | SQL/Leetcode/gpt/ | LEFT JOIN理解 | -| 7 | SQL: PostgreSQL実装 | CombineTwoTables_postgre.md | DISTINCT ON習得 | -| 8 | SQL: Pandas実装 | CombineTwoTables_pandas.md | DataFrame操作 | +| Week | 活動 | 使用リソース | 達成目標 | +| ---- | ------------------------------- | --------------------------- | ---------------- | +| 5 | FSM: Valid Number | Mathematics/FSM/ | 状態遷移図の理解 | +| 6 | SQL: Combine Two Tables (MySQL) | SQL/Leetcode/gpt/ | LEFT JOIN理解 | +| 7 | SQL: PostgreSQL実装 | CombineTwoTables_postgre.md | DISTINCT ON習得 | +| 8 | SQL: Pandas実装 | CombineTwoTables_pandas.md | DataFrame操作 | **達成目標**: + - ✅ FSMの状態遷移理解 - ✅ SQL JOINパターン - ✅ 3プラットフォームの特徴理解 @@ -1205,72 +1207,73 @@ graph LR Problem[選択した問題] --> Dim1[次元1: AI比較] Problem --> Dim2[次元2: 言語比較] Problem --> Dim3[次元3: 階層比較] - + Dim1 --> Claude[Claude実装
速度優先] Dim1 --> GPT[GPT実装
安全性優先] - + Dim2 --> Py[Python
動的型] Dim2 --> TS[TypeScript
静的型] Dim2 --> JS[JavaScript
動的型] - + Dim3 --> T1[Tier 1
静的理解] Dim3 --> T2[Tier 2
実行可視化] Dim3 --> T3[Tier 3
パフォーマンス] - + style Problem fill:#4A90E2,color:#fff style Claude fill:#7ED321,color:#fff style GPT fill:#F5A623,color:#fff ``` **学習活動**: + 1. **AI実装比較** (10日間) - - Claude vs GPT のコーディングスタイル分析 - - 速度と安全性のトレードオフ理解 - - 5問を両AI実装で比較 + - Claude vs GPT のコーディングスタイル分析 + - 速度と安全性のトレードオフ理解 + - 5問を両AI実装で比較 2. **言語間比較** (10日間) - - Python/TypeScript/JavaScript の実装パターン - - 型システムの影響分析 - - 同一アルゴリズムを3言語で実装 + - Python/TypeScript/JavaScript の実装パターン + - 型システムの影響分析 + - 同一アルゴリズムを3言語で実装 3. **階層進行分析** (10日間) - - Tier 1 → 2 → 3 の学習効果測定 - - インタラクティブ要素の活用 - - 自分に最適な学習スタイル発見 + - Tier 1 → 2 → 3 の学習効果測定 + - インタラクティブ要素の活用 + - 自分に最適な学習スタイル発見 #### Month 4: パターン認識 **目標**: アルゴリズムパターンの体系的理解 -| トピック | 問題数 | 重点学習項目 | 所要時間 | -|---------|--------|-------------|---------| -| **Dynamic Programming** | 10問 | • メモ化
• ボトムアップ vs トップダウン
• 状態遷移式 | 10日 | -| **Trees** | 8問 | • DFS/BFS
• 再帰
• バランス木 | 8日 | -| **SQL Window Functions** | 5問 | • LAG/LEAD
• RANK/DENSE_RANK
• パーティション | 5日 | -| **復習と応用** | - | • 混合問題
• 模擬面接 | 7日 | +| トピック | 問題数 | 重点学習項目 | 所要時間 | +| ------------------------ | ------ | ------------------------------------------------------------ | -------- | +| **Dynamic Programming** | 10問 | • メモ化
• ボトムアップ vs トップダウン
• 状態遷移式 | 10日 | +| **Trees** | 8問 | • DFS/BFS
• 再帰
• バランス木 | 8日 | +| **SQL Window Functions** | 5問 | • LAG/LEAD
• RANK/DENSE_RANK
• パーティション | 5日 | +| **復習と応用** | - | • 混合問題
• 模擬面接 | 7日 | **パターン認識マップ**: ```mermaid graph TD Pattern[アルゴリズムパターン] - + Pattern --> DP[Dynamic Programming] Pattern --> Tree[Tree Traversal] Pattern --> SQL[SQL Patterns] - + DP --> DP1[1D DP
Fibonacci, Climbing Stairs] DP --> DP2[2D DP
Grid Path, Edit Distance] DP --> DP3[Knapsack
0/1, Unbounded] - + Tree --> Tree1[DFS
PreOrder, InOrder, PostOrder] Tree --> Tree2[BFS
Level Order] Tree --> Tree3[Binary Search Tree
Insert, Delete, Search] - + SQL --> SQL1[JOIN
INNER, LEFT, RIGHT] SQL --> SQL2[Window Functions
LAG, LEAD, RANK] SQL --> SQL3[Aggregation
GROUP BY, HAVING] - + style Pattern fill:#4A90E2,color:#fff style DP fill:#7ED321,color:#fff style Tree fill:#F5A623,color:#fff @@ -1284,32 +1287,33 @@ graph TD **学習プログラム**: 1. **言語間パフォーマンス比較** (10日間) - ```mermaid - graph LR - Bench[ベンチマーク] --> Lang1[Python実装] - Bench --> Lang2[TypeScript実装] - Bench --> Lang3[JavaScript実装] - - Lang1 --> Result1[実行時間: Xms
メモリ: Ymb] - Lang2 --> Result2[実行時間: Xms
メモリ: Ymb] - Lang3 --> Result3[実行時間: Xms
メモリ: Ymb] - - Result1 --> Analysis[分析とレポート] - Result2 --> Analysis - Result3 --> Analysis - - style Bench fill:#4A90E2,color:#fff - ``` + + ```mermaid + graph LR + Bench[ベンチマーク] --> Lang1[Python実装] + Bench --> Lang2[TypeScript実装] + Bench --> Lang3[JavaScript実装] + + Lang1 --> Result1[実行時間: Xms
メモリ: Ymb] + Lang2 --> Result2[実行時間: Xms
メモリ: Ymb] + Lang3 --> Result3[実行時間: Xms
メモリ: Ymb] + + Result1 --> Analysis[分析とレポート] + Result2 --> Analysis + Result3 --> Analysis + + style Bench fill:#4A90E2,color:#fff + ``` 2. **AI実装の速度差分析** (10日間) - - Claude実装: 整数センチネルの効果測定 - - GPT実装: 検証オーバーヘッドの定量化 - - トレードオフの実データ取得 + - Claude実装: 整数センチネルの効果測定 + - GPT実装: 検証オーバーヘッドの定量化 + - トレードオフの実データ取得 3. **最適化技術の実験** (10日間) - - メモ化戦略 - - インプレース操作 - - 時間/空間のトレードオフ + - メモ化戦略 + - インプレース操作 + - 時間/空間のトレードオフ **使用ツール**: README_react.html (Tier 3) のベンチマーク機能 @@ -1324,31 +1328,32 @@ graph TD Contest[競技プログラミング] --> Platform1[LeetCode Contest] Contest --> Platform2[Codeforces] Contest --> Platform3[AtCoder] - + Platform1 --> LC1[Weekly Contest] Platform1 --> LC2[Biweekly Contest] - + Platform2 --> CF1[Div. 2/3 Contest] Platform2 --> CF2[Educational Rounds] - + Platform3 --> AC1[Beginner Contest] Platform3 --> AC2[Regular Contest] - + LC1 --> Strategy[Claude実装活用
速度優先戦略] LC2 --> Strategy CF1 --> Strategy CF2 --> Strategy AC1 --> Strategy AC2 --> Strategy - + Strategy --> Improve[継続的改善] - + style Contest fill:#4A90E2,color:#fff style Strategy fill:#7ED321,color:#fff style Improve fill:#F5A623,color:#fff ``` **活動計画**: + - **週次**: LeetCode Weekly/Biweekly Contest参加 - **月次**: Codeforces Div.2 参加 (月2回) - **月次**: AtCoder Beginner Contest参加 (週1回) @@ -1370,23 +1375,23 @@ graph TD Production[本番環境開発] --> API[APIライブラリ開発] Production --> Enterprise[エンタープライズシステム] Production --> Testing[テストカバレッジ向上] - + API --> API1[GPT実装パターン活用] API --> API2[包括的エラー処理] API --> API3[型安全性重視] - + Enterprise --> E1[スケーラビリティ] Enterprise --> E2[保守性] Enterprise --> E3[セキュリティ] - + Testing --> T1[ユニットテスト] Testing --> T2[統合テスト] Testing --> T3[エッジケース網羅] - + API3 --> Quality[高品質コード] E3 --> Quality T3 --> Quality - + style Production fill:#4A90E2,color:#fff style API fill:#F5A623,color:#fff style Quality fill:#7ED321,color:#fff @@ -1395,23 +1400,24 @@ graph TD **開発プロジェクト例**: 1. **データ処理ライブラリ** - - GPT TypeScript実装を基盤に使用 - - 完全な型定義 - - 包括的エラーハンドリング - - ドキュメント自動生成 + - GPT TypeScript実装を基盤に使用 + - 完全な型定義 + - 包括的エラーハンドリング + - ドキュメント自動生成 2. **アルゴリズムAPIサービス** - - RESTful API設計 - - 入力検証とサニタイゼーション - - レート制限実装 - - モニタリングとロギング + - RESTful API設計 + - 入力検証とサニタイゼーション + - レート制限実装 + - モニタリングとロギング 3. **テスト駆動開発** - - リポジトリのエッジケースを参考 - - 100%コードカバレッジ目標 - - CI/CDパイプライン構築 + - リポジトリのエッジケースを参考 + - 100%コードカバレッジ目標 + - CI/CDパイプライン構築 **品質チェックリスト**: + - ✅ 型安全性 (TypeScript strict mode) - ✅ エラーハンドリング (try-catch, 型ガード) - ✅ 入力検証 (境界値、null/undefined) @@ -1428,19 +1434,19 @@ graph LR Contrib[リポジトリへの貢献] --> NewProb[新問題の追加] Contrib --> DocImprove[ドキュメント改善] Contrib --> BugFix[バグ修正・最適化] - + NewProb --> NP1[新しいLeetCode問題] NewProb --> NP2[18成果物の生成] NewProb --> NP3[Pull Request作成] - + DocImprove --> DI1[誤字脱字修正] DocImprove --> DI2[説明の明確化] DocImprove --> DI3[図解の追加] - + BugFix --> BF1[コードバグ修正] BugFix --> BF2[パフォーマンス改善] BugFix --> BF3[テストケース追加] - + style Contrib fill:#4A90E2,color:#fff style NewProb fill:#7ED321,color:#fff style DocImprove fill:#F5A623,color:#fff @@ -1450,25 +1456,26 @@ graph LR **貢献活動例**: 1. **新問題の追加** (高度) - - LeetCode新問題を選択 - - Claude/GPT両実装を作成 - - Python/TypeScript/JavaScript全言語対応 - - 3段階ドキュメント作成 - - Pull Request提出 + - LeetCode新問題を選択 + - Claude/GPT両実装を作成 + - Python/TypeScript/JavaScript全言語対応 + - 3段階ドキュメント作成 + - Pull Request提出 2. **ドキュメント改善** (中級) - - README.mdの誤字修正 - - アルゴリズム説明の明確化 - - Mermaid図の追加・改善 - - 翻訳の改善 + - README.mdの誤字修正 + - アルゴリズム説明の明確化 + - Mermaid図の追加・改善 + - 翻訳の改善 3. **バグ修正・最適化** (全レベル) - - Issueの確認と修正 - - パフォーマンス改善提案 - - テストケースの追加 - - コードレビュー参加 + - Issueの確認と修正 + - パフォーマンス改善提案 + - テストケースの追加 + - コードレビュー参加 **コントリビューションプロセス**: + 1. リポジトリをFork 2. ローカルでブランチ作成 3. 変更を実装・テスト @@ -1488,26 +1495,26 @@ graph LR ```mermaid graph TD Core[Algorithm-DataStructures-Math-SQL
核心価値] - + Core --> V1[教育的透明性] Core --> V2[マルチ次元比較] Core --> V3[プログレッシブ学習] Core --> V4[実践的応用] - + V1 --> V1_1[ゼロ外部依存
標準ライブラリのみ] V1 --> V1_2[完全なコード公開
ブラックボックスなし] - + V2 --> V2_1[2 AI実装
Claude vs GPT] V2 --> V2_2[3言語対応
Python/TS/JS] V2 --> V2_3[競技vs本番
速度vs安全性] - + V3 --> V3_1[3段階ドキュメント
初心者→上級者] V3 --> V3_2[段階的複雑化
静的→動的→React] - + V4 --> V4_1[競技プログラミング
LeetCode/Codeforces] V4 --> V4_2[技術面接対策
実装パターン] V4 --> V4_3[本番環境開発
エンタープライズ品質] - + style Core fill:#4A90E2,color:#fff style V1 fill:#7ED321,color:#fff style V2 fill:#F5A623,color:#fff @@ -1519,34 +1526,34 @@ graph TD #### 🎯 4つのコア領域 -| 領域 | 問題数 | 主要パターン | -|------|--------|-------------| -| **Algorithm** | 多数 | 二分探索、動的計画法、貪欲法 | -| **DataStructures** | 多数 | 連結リスト、木構造、グラフ | -| **Mathematics** | 多数 | FSM、幾何学、数論 | -| **SQL** | 多数 | JOIN、ウィンドウ関数、集約 | +| 領域 | 問題数 | 主要パターン | +| ------------------ | ------ | ---------------------------- | +| **Algorithm** | 多数 | 二分探索、動的計画法、貪欲法 | +| **DataStructures** | 多数 | 連結リスト、木構造、グラフ | +| **Mathematics** | 多数 | FSM、幾何学、数論 | +| **SQL** | 多数 | JOIN、ウィンドウ関数、集約 | #### 🤖 2つのAIプロバイダー -| AI | 哲学 | 最適用途 | -|----|------|---------| -| **Claude** | 速度優先 | 競技プログラミング、アルゴリズムコンテスト | -| **GPT** | 安全性優先 | 本番API、エンタープライズシステム | +| AI | 哲学 | 最適用途 | +| ---------- | ---------- | ------------------------------------------ | +| **Claude** | 速度優先 | 競技プログラミング、アルゴリズムコンテスト | +| **GPT** | 安全性優先 | 本番API、エンタープライズシステム | #### 💻 3つの言語 -| 言語 | 特徴 | 学習価値 | -|------|------|---------| -| **Python** | 動的型、読みやすい | アルゴリズムの直感理解 | -| **TypeScript** | 静的型、型安全 | 大規模開発、保守性 | -| **JavaScript** | 動的型、Web標準 | フロントエンド、柔軟性 | +| 言語 | 特徴 | 学習価値 | +| -------------- | ------------------ | ---------------------- | +| **Python** | 動的型、読みやすい | アルゴリズムの直感理解 | +| **TypeScript** | 静的型、型安全 | 大規模開発、保守性 | +| **JavaScript** | 動的型、Web標準 | フロントエンド、柔軟性 | #### 📚 3つのドキュメント階層 -| 階層 | ファイル | 対象 | 主な価値 | -|------|---------|------|---------| -| **Tier 1** | README.md | 初心者 | 基本概念、計算量理解 | -| **Tier 2** | README.html | 中級者 | 実行可視化、デバッグ | +| 階層 | ファイル | 対象 | 主な価値 | +| ---------- | ----------------- | ------ | -------------------------- | +| **Tier 1** | README.md | 初心者 | 基本概念、計算量理解 | +| **Tier 2** | README.html | 中級者 | 実行可視化、デバッグ | | **Tier 3** | README_react.html | 上級者 | パフォーマンス分析、AI比較 | ### 学習成果の全体像 @@ -1557,27 +1564,27 @@ graph TB Month2 --> Month4[4ヶ月後] Month4 --> Month6[6ヶ月後] Month6 --> Year1[1年後] - + Month2 --> Skill2[基礎スキル獲得] Skill2 --> S2_1[✅ アルゴリズム基本理解] Skill2 --> S2_2[✅ 計算量解析能力] Skill2 --> S2_3[✅ 基本実装パターン] - + Month4 --> Skill4[実践スキル獲得] Skill4 --> S4_1[✅ マルチ言語実装] Skill4 --> S4_2[✅ パターン認識能力] Skill4 --> S4_3[✅ デバッグ技術] - + Month6 --> Skill6[応用スキル獲得] Skill6 --> S6_1[✅ パフォーマンス最適化] Skill6 --> S6_2[✅ AI実装比較理解] Skill6 --> S6_3[✅ 本番環境コード作成] - + Year1 --> SkillMaster[マスターレベル] SkillMaster --> SM1[🏆 競技プログラミング入賞] SkillMaster --> SM2[🏆 技術面接合格] SkillMaster --> SM3[🏆 OSSコントリビューション] - + style Start fill:#4A90E2,color:#fff style Month2 fill:#7ED321,color:#fff style Month4 fill:#F5A623,color:#fff @@ -1588,18 +1595,21 @@ graph TB ### 最終的な達成目標 **技術スキル**: + - ✅ 50+のアルゴリズムパターンの完全理解 - ✅ Python/TypeScript/JavaScript での実装能力 - ✅ O記法による計算量解析の習熟 - ✅ 競技プログラミングと本番環境の両方での実践力 **ソフトスキル**: + - ✅ 問題分解能力 - ✅ トレードオフ分析力 - ✅ コードレビュー能力 - ✅ 技術的コミュニケーション力 **キャリア成果**: + - 🎯 技術面接での高評価 - 🎯 競技プログラミングでのレーティング向上 - 🎯 高品質なコード作成能力 @@ -1618,13 +1628,13 @@ graph TB ### 推奨学習リソース -| カテゴリ | リソース | 用途 | -|---------|---------|------| -| **アルゴリズム基礎** | Introduction to Algorithms (CLRS) | 理論的基礎 | +| カテゴリ | リソース | 用途 | +| ---------------------- | --------------------------------- | -------------- | +| **アルゴリズム基礎** | Introduction to Algorithms (CLRS) | 理論的基礎 | | **競技プログラミング** | Competitive Programmer's Handbook | 実践テクニック | -| **Python** | Python公式ドキュメント | 言語仕様 | -| **TypeScript** | TypeScript Handbook | 型システム | -| **SQL** | SQL Performance Explained | 最適化技術 | +| **Python** | Python公式ドキュメント | 言語仕様 | +| **TypeScript** | TypeScript Handbook | 型システム | +| **SQL** | SQL Performance Explained | 最適化技術 | ### コミュニティサポート