diff --git a/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md new file mode 100644 index 00000000..a7e14fc9 --- /dev/null +++ b/Algorithm/BinarySearch/leetcode/69. Sqrt(x)/Claude4.6 extended/README.md @@ -0,0 +1,392 @@ +# Sqrt(x) - 整数平方根を二分探索で求める + + + +## 目次 + +- [Overview (概要)](#overview) +- [Algorithm (アルゴリズム)](#algorithm) +- [Complexity (計算量)](#complexity) +- [Implementation (実装)](#implementation) +- [Optimization (最適化)](#optimization) + +--- + +
+ 二分探索(Binary Search)による O(log n) 実装 +
+ +
+ 非負整数
+ x を受け取り、
+ floor(√x)(小数点以下切り捨て)を返す。
+ math.sqrt・ **・
+ pow(x, 0.5)
+ などの組み込み指数演算は使用禁止。
+
0 ≤ x ≤ 2³¹ - 1(非負整数)
+ math.sqrt
+ 禁止
+ **
+ 演算子 禁止
+ pow(x, 0.5)
+ 禁止
+ class Solution:
+ def mySqrt(self, x: int) -> int:
+ # エッジケース: x=0, x=1 は即リターン
+ if x < 2:
+ return x
+
+ # 探索範囲: [1, x // 2]
+ # 根拠: x >= 2 のとき floor(√x) <= x // 2 が常に成立
+ low: int = 1
+ high: int = x >> 1 # ビットシフトで x // 2(CPython 最速)
+
+ # Loop Invariant:
+ # (low - 1)^2 <= x かつ (high + 1)^2 > x
+ # → ループ終了時: high = floor(√x)
+ while low <= high:
+ mid: int = (low + high) >> 1 # 中点計算
+ sq: int = mid * mid # Python int は任意精度 → オーバーフローなし
+
+ if sq == x:
+ return mid # 完全平方数: 即リターン
+ elif sq < x:
+ low = mid + 1 # mid が小さすぎる → 下限を引き上げ
+ else:
+ high = mid - 1 # mid が大きすぎる → 上限を引き下げ
+
+ # ループ終了後: high = floor(√x)
+ return high
+
+graph TD
+ Start["開始: mySqrt(x)"]
+ CheckEdge{"x < 2?"}
+ ReturnX["return x"]
+ Init["初期化: low=1, high=x/2"]
+ LoopCheck{"low <= high?"}
+ ReturnHigh["return high"]
+ CalcMid["中点計算
mid=(low+high)/2"]
+ Compare{"sq vs x"}
+ ReturnMid["return mid"]
+ UpdateLow["low=mid+1"]
+ UpdateHigh["high=mid-1"]
+ End["終了"]
+
+ Start --> CheckEdge
+ CheckEdge -->|Yes| ReturnX
+ CheckEdge -->|No| Init
+ Init --> LoopCheck
+ LoopCheck -->|No| ReturnHigh
+ LoopCheck -->|Yes| CalcMid
+ CalcMid --> Compare
+ Compare -->|Equal| ReturnMid
+ Compare -->|Less| UpdateLow
+ Compare -->|Greater| UpdateHigh
+ UpdateLow --> LoopCheck
+ UpdateHigh --> LoopCheck
+ ReturnX --> End
+ ReturnMid --> End
+ ReturnHigh --> End
+
+ style Start fill:#d1fae5,stroke:#10b981,stroke-width:3px
+ style End fill:#d1fae5,stroke:#10b981,stroke-width:3px
+ style CheckEdge fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style LoopCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style Compare fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style ReturnX fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style ReturnMid fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style ReturnHigh fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style Init fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style CalcMid fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style UpdateLow fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style UpdateHigh fill:#fee2e2,stroke:#dc2626,stroke-width:2px
+
+
+ フローの説明:
+ 1. エッジケース判定: x < 2 の場合は x をそのまま返す(0→0,
+ 1→1)
+ 2. 探索範囲初期化: low=1,
+ high=x>>1(x/2)で探索上限を半分に削減
+ 3. 二分探索ループ: low>high になるまで
+ mid=(low+high)>>1 を計算
+ 4. 三方比較: sq==x(即リターン)/ sq<x(low引き上げ)/
+ sq>x(high引き下げ)
+ 5. ループ終了: high = floor(√x) が確定 → return high
+ ── 紫の破線:
+ ループバック(探索範囲を狭めて次のイテレーションへ)
+
| + アプローチ + | ++ 時間 + | ++ 空間 + | ++ 誤差 + | ++ 保守性 + | ++ 選択 + | +
|---|---|---|---|---|---|
| 線形探索 | ++ O(√n) + | ++ O(1) + | ++ なし + | +★★★ | ++ ✗ 遅い + | +
| + 二分探索 ✅ + | ++ O(log n) + | ++ O(1) + | ++ なし + | ++ ★★★ + | ++ ✅ 最適 + | +
| ニュートン法 | ++ O(log log n) + | ++ O(1) + | ++ float誤差 + | +★★☆ | ++ △ 誤差リスク + | +
| math.isqrt() | ++ O(log n) + | ++ O(1) + | ++ なし + | +★★★ | ++ 🚫 禁止 + | +
+ 二分探索(Binary Search)による O(log n) 実装 +
+ +
+ 非負整数
+ x を受け取り、
+ floor(√x)(小数点以下切り捨て)を返す。
+ math.sqrt・ **・
+ pow(x, 0.5)
+ などの組み込み指数演算は使用禁止。
+
0 ≤ x ≤ 2³¹ - 1(非負整数)
+ math.sqrt
+ 禁止
+ **
+ 演算子 禁止
+ pow(x, 0.5)
+ 禁止
+ class Solution:
+ def mySqrt(self, x: int) -> int:
+ # エッジケース: x=0, x=1 は即リターン
+ if x < 2:
+ return x
+
+ # 探索範囲: [1, x // 2]
+ # 根拠: x >= 2 のとき floor(√x) <= x // 2 が常に成立
+ low: int = 1
+ high: int = x >> 1 # ビットシフトで x // 2(CPython 最速)
+
+ # Loop Invariant:
+ # (low - 1)^2 <= x かつ (high + 1)^2 > x
+ # → ループ終了時: high = floor(√x)
+ while low <= high:
+ mid: int = (low + high) >> 1 # 中点計算
+ sq: int = mid * mid # Python int は任意精度 → オーバーフローなし
+
+ if sq == x:
+ return mid # 完全平方数: 即リターン
+ elif sq < x:
+ low = mid + 1 # mid が小さすぎる → 下限を引き上げ
+ else:
+ high = mid - 1 # mid が大きすぎる → 上限を引き下げ
+
+ # ループ終了後: high = floor(√x)
+ return high
+
+graph TD
+ Start["開始: mySqrt(x)"]
+ CheckEdge{"x < 2?"}
+ ReturnX["return x"]
+ Init["初期化: low=1, high=x/2"]
+ LoopCheck{"low <= high?"}
+ ReturnHigh["return high"]
+ CalcMid["中点計算
mid=(low+high)/2"]
+ Compare{"sq vs x"}
+ ReturnMid["return mid"]
+ UpdateLow["low=mid+1"]
+ UpdateHigh["high=mid-1"]
+ End["終了"]
+
+ Start --> CheckEdge
+ CheckEdge -->|Yes| ReturnX
+ CheckEdge -->|No| Init
+ Init --> LoopCheck
+ LoopCheck -->|No| ReturnHigh
+ LoopCheck -->|Yes| CalcMid
+ CalcMid --> Compare
+ Compare -->|Equal| ReturnMid
+ Compare -->|Less| UpdateLow
+ Compare -->|Greater| UpdateHigh
+ UpdateLow --> LoopCheck
+ UpdateHigh --> LoopCheck
+ ReturnX --> End
+ ReturnMid --> End
+ ReturnHigh --> End
+
+ style Start fill:#d1fae5,stroke:#10b981,stroke-width:3px
+ style End fill:#d1fae5,stroke:#10b981,stroke-width:3px
+ style CheckEdge fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style LoopCheck fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style Compare fill:#fef3c7,stroke:#f59e0b,stroke-width:2px
+ style ReturnX fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style ReturnMid fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style ReturnHigh fill:#d1fae5,stroke:#059669,stroke-width:2px
+ style Init fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style CalcMid fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style UpdateLow fill:#e0f2fe,stroke:#0284c7,stroke-width:2px
+ style UpdateHigh fill:#fee2e2,stroke:#dc2626,stroke-width:2px
+
+
+ フローの説明:
+ 1. エッジケース判定: x < 2 の場合は x をそのまま返す(0→0,
+ 1→1)
+ 2. 探索範囲初期化: low=1,
+ high=x>>1(x/2)で探索上限を半分に削減
+ 3. 二分探索ループ: low>high になるまで
+ mid=(low+high)>>1 を計算
+ 4. 三方比較: sq==x(即リターン)/ sq<x(low引き上げ)/
+ sq>x(high引き下げ)
+ 5. ループ終了: high = floor(√x) が確定 → return high
+ ── 紫の破線:
+ ループバック(探索範囲を狭めて次のイテレーションへ)
+
| + アプローチ + | ++ 時間 + | ++ 空間 + | ++ 誤差 + | ++ 保守性 + | ++ 選択 + | +
|---|---|---|---|---|---|
| 線形探索 | ++ O(√n) + | ++ O(1) + | ++ なし + | +★★★ | ++ ✗ 遅い + | +
| + 二分探索 ✅ + | ++ O(log n) + | ++ O(1) + | ++ なし + | ++ ★★★ + | ++ ✅ 最適 + | +
| ニュートン法 | ++ O(log log n) + | ++ O(1) + | ++ float誤差 + | +★★☆ | ++ △ 誤差リスク + | +
| math.isqrt() | ++ O(log n) + | ++ O(1) + | ++ なし + | +★★★ | ++ 🚫 禁止 + | +
161 interactive lessons across 6 domains
+162 interactive lessons across 6 domains