Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "464fa3b5",
"metadata": {},
"source": [
"# Python コーディング問題: Plus One\n",
"\n",
"## 1. 問題分析結果\n",
"\n",
"### 競技プログラミング視点\n",
"\n",
"- **制約分析**: \n",
" - 配列長: 1 ≤ len(digits) ≤ 100 → O(n)アルゴリズムで十分\n",
" - 各要素: 0 ≤ digits[i] ≤ 9 → 整数演算のみで処理可能\n",
" - 先頭に0なし → エッジケース考慮が簡素化\n",
" \n",
"- **最速手法**: \n",
" - 右から左への単一ループ(O(n))\n",
" - 早期リターンで平均O(1)~O(n)\n",
" - in-place変更で追加メモリ最小化\n",
" \n",
"- **メモリ最小化**: \n",
" - 基本的にin-place操作でO(1)\n",
" - 全桁9のケースのみO(n)の新規メモリ\n",
" \n",
"- **CPython最適化**: \n",
" - リスト操作は全てC実装で高速\n",
" - `range()`の逆順イテレーションは効率的\n",
" - リスト結合は`[1] + digits`より`[1, *digits]`が推奨\n",
"\n",
"### 業務開発視点\n",
"\n",
"- **型安全設計**: \n",
" - `List[int]`での厳密な型ヒント\n",
" - pylance完全対応の型アノテーション\n",
" - Optional型での明示的なNone処理\n",
" \n",
"- **エラーハンドリング**: \n",
" - 入力検証(空配列、型チェック、範囲チェック)\n",
" - ValueError/TypeErrorの適切な使い分け\n",
" - docstringでの例外明記\n",
" \n",
"- **可読性**: \n",
" - 筆算アルゴリズムの直感的な実装\n",
" - 変数名の明確化(carry, digit等)\n",
" - 適切なコメント配置\n",
"\n",
"### Python特有分析\n",
"\n",
"- **データ構造選択**: \n",
" - リスト操作が中心 → `list`が最適\n",
" - 両端操作は少ない → `deque`不要\n",
" - 順序保持必須 → `set`は不適\n",
" \n",
"- **標準ライブラリ活用度**: \n",
" - この問題では標準ライブラリ不要(シンプルなリスト操作のみ)\n",
" - `collections`、`itertools`等は過剰\n",
" \n",
"- **CPython最適化度**: \n",
" - リスト走査は組み込みイテレータで高速\n",
" - リスト結合はスライシングよりスプレッド演算子\n",
" - インデックスアクセスはC実装で高速\n",
"\n",
"## 2. アルゴリズム比較表\n",
"\n",
"|アプローチ|時間計算量|空間計算量|Python実装コスト|可読性|標準ライブラリ活用|CPython最適化|備考|\n",
"|---------|---------|---------|---------------|------|----------------|------------|-----|\n",
"|右から走査(in-place)|O(n)|O(1)*|低|★★★|不要|適|*最悪時O(n)|\n",
"|右から走査(immutable)|O(n)|O(n)|低|★★☆|不要|適|常に新規配列生成|\n",
"|文字列変換|O(n)|O(n)|中|★☆☆|str, int組み込み|不適|型変換コスト大|\n",
"|再帰処理|O(n)|O(n)|高|★☆☆|不要|不適|スタック使用|\n",
"|BigInt演算|O(n)|O(n)|低|★★☆|組み込みint|不適|配列長制限なし時のみ有効|\n",
"\n",
"## 3. 採用アルゴリズムと根拠\n",
"\n",
"### 選択理由\n",
"\n",
"**右から走査(in-place)方式**を採用\n",
"\n",
"1. **計算量優位性**: \n",
" - 時間: O(n)で最適、平均的には早期リターンでより高速\n",
" - 空間: ほぼO(1)、最悪ケース(all 9s)のみO(n)\n",
"\n",
"2. **実装効率**: \n",
" - Pythonのリスト操作は直感的\n",
" - 標準的な筆算アルゴリズムで理解容易\n",
" - コード量が少なく保守性高い\n",
"\n",
"3. **保守性**: \n",
" - エッジケースが明確\n",
" - デバッグが容易\n",
" - チーム開発でも理解しやすい\n",
"\n",
"4. **Python特性**: \n",
" - リスト操作はすべてC実装で高速\n",
" - 型アノテーションが自然\n",
" - pylanceとの相性良好\n",
"\n",
"### Python最適化戦略\n",
"\n",
"1. **逆順イテレーション**: `range(len(digits)-1, -1, -1)`でC実装の高速イテレータ活用\n",
"2. **早期リターン**: 繰り上がり不要時に即座に処理終了\n",
"3. **スプレッド演算子**: `[1, *digits]`で効率的なリスト結合\n",
"4. **in-place変更**: LeetCode形式では許容され、メモリ効率的\n",
"\n",
"### トレードオフ\n",
"\n",
"- **可読性 vs パフォーマンス**: in-place変更は可読性を損なわないため両立\n",
"- **型安全性 vs 簡潔性**: 型ヒントを付けても簡潔性は維持\n",
"- **エラーハンドリング vs 速度**: 競プ版ではエラーチェック省略で高速化\n",
"\n",
"## 4. 実装パターン\n",
"\n",
"### 業務開発版(型安全・エラーハンドリング重視)\n",
"Analyze Complexity\n",
"Runtime 0 ms\n",
"Beats 100.00%\n",
"Memory 19.20 MB\n",
"Beats 19.41%\n",
"```python\n",
"from typing import List\n",
"\n",
"class Solution:\n",
" \"\"\"\n",
" Plus One 問題の解決クラス\n",
" \n",
" 大きな整数を表す配列に1を加算する処理を提供\n",
" \"\"\"\n",
" \n",
" def plusOne(self, digits: List[int]) -> List[int]:\n",
" \"\"\"\n",
" 整数配列に1を加算する(業務開発版)\n",
" \n",
" Args:\n",
" digits: 各桁を表す整数リスト(最上位桁が先頭)\n",
" 各要素は0-9の範囲内である必要がある\n",
" \n",
" Returns:\n",
" 1を加算した結果の整数配列\n",
" \n",
" Raises:\n",
" TypeError: 入力が配列でない、または要素が整数でない場合\n",
" ValueError: 配列が空、または要素が0-9の範囲外の場合\n",
" \n",
" Examples:\n",
" >>> Solution().plusOne([1, 2, 3])\n",
" [1, 2, 4]\n",
" >>> Solution().plusOne([9, 9, 9])\n",
" [1, 0, 0, 0]\n",
" \n",
" Time Complexity: O(n) where n = len(digits)\n",
" Space Complexity: O(1) 平均、O(n) 最悪時(all 9s)\n",
" \"\"\"\n",
" # 入力検証\n",
" self._validate_input(digits)\n",
" \n",
" # 右から左へ走査\n",
" for i in range(len(digits) - 1, -1, -1):\n",
" # 現在の桁が9未満の場合\n",
" if digits[i] < 9:\n",
" digits[i] += 1\n",
" return digits # 繰り上がり不要、即座に返却\n",
" \n",
" # 現在の桁が9の場合、0にして繰り上がり継続\n",
" digits[i] = 0\n",
" \n",
" # 全桁が9だった場合(例: [9,9,9] → [1,0,0,0])\n",
" return [1, *digits]\n",
" \n",
" def _validate_input(self, digits: List[int]) -> None:\n",
" \"\"\"\n",
" 入力配列の検証\n",
" \n",
" Args:\n",
" digits: 検証対象の配列\n",
" \n",
" Raises:\n",
" TypeError: 型が不正な場合\n",
" ValueError: 値が制約を満たさない場合\n",
" \"\"\"\n",
" if not isinstance(digits, list):\n",
" raise TypeError(\"Input must be a list\")\n",
" \n",
" if not digits:\n",
" raise ValueError(\"Input list cannot be empty\")\n",
" \n",
" if len(digits) > 100:\n",
" raise ValueError(\"Input size exceeds constraint (max 100)\")\n",
" \n",
" for i, digit in enumerate(digits):\n",
" if not isinstance(digit, int):\n",
" raise TypeError(f\"Element at index {i} must be an integer\")\n",
" \n",
" if not 0 <= digit <= 9:\n",
" raise ValueError(\n",
" f\"Element at index {i} ({digit}) must be in range [0, 9]\"\n",
" )\n",
Comment on lines +192 to +199

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

find . -name "PlusOne_python.ipynb" -type f

Repository: myoshi2891/Algorithm-DataStructures-Math-SQL

Length of output: 166


🏁 Script executed:

wc -l "./Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/PlusOne_python.ipynb"

Repository: myoshi2891/Algorithm-DataStructures-Math-SQL

Length of output: 170


🏁 Script executed:

cat -n "./Algorithm/Other/leetcode/66. Plus One/Claude Sonnet 4.5/PlusOne_python.ipynb" | sed -n '180,210p'

Repository: myoshi2891/Algorithm-DataStructures-Math-SQL

Length of output: 1564


🏁 Script executed:

python3 << 'EOF'
# Verify if bool is instance of int in Python
print("isinstance(True, int):", isinstance(True, int))
print("isinstance(False, int):", isinstance(False, int))
print("isinstance(True, bool):", isinstance(True, bool))
print("isinstance(False, bool):", isinstance(False, bool))

# Test the validation logic
digit = True
if not isinstance(digit, int):
    print("Would raise TypeError for True")
else:
    print("True passes isinstance(digit, int) check")

# Test the proposed fix
digit = True
if not isinstance(digit, int) or isinstance(digit, bool):
    print("With fix: True would raise TypeError")
else:
    print("With fix: True would still pass")
EOF

Repository: myoshi2891/Algorithm-DataStructures-Math-SQL

Length of output: 281


bool が整数として通過してしまう入力検証

isinstance(digit, int) を使用していますが、Pythonでは boolint のサブクラスであるため、TrueFalse が整数として許可されてしまいます。より厳密な型検証が必要な場合は bool を除外してください。

修正案
-            if not isinstance(digit, int):
+            if not isinstance(digit, int) or isinstance(digit, bool):
                 raise TypeError(f"Element at index {i} must be an integer")
🤖 Prompt for AI Agents
In `@Algorithm/Other/leetcode/66`. Plus One/Claude Sonnet 4.5/PlusOne_python.ipynb
around lines 192 - 199, The input validation loop over digits incorrectly
accepts booleans because isinstance(digit, int) returns True for bool; update
the check in the loop that currently reads "for i, digit in enumerate(digits):"
to exclude bools—e.g., replace the isinstance(digit, int) check with a strict
type check such as type(digit) is int or add an extra condition like
isinstance(digit, int) and not isinstance(digit, bool) so that True/False are
rejected before the range check in the function handling digits (the loop using
variables i and digit).

" \n",
" # 先頭が0でないことを確認(制約より)\n",
" if len(digits) > 1 and digits[0] == 0:\n",
" raise ValueError(\"Leading zero is not allowed\")\n",
"```\n",
"\n",
"### 競技プログラミング版(パフォーマンス最優先)\n",
"Analyze Complexity\n",
"Runtime 0 ms\n",
"Beats 100.00%\n",
"Memory 19.25 MB\n",
"Beats 17.57%\n",
"```python\n",
"from typing import List\n",
"\n",
"class Solution:\n",
" def plusOne(self, digits: List[int]) -> List[int]:\n",
" \"\"\"\n",
" 整数配列に1を加算する(競プ最適化版)\n",
" \n",
" エラーハンドリング省略、性能最優先\n",
" \n",
" Time Complexity: O(n)\n",
" Space Complexity: O(1) 平均、O(n) 最悪時\n",
" \"\"\"\n",
" # 右から左へ走査(インデックス逆順)\n",
" for i in range(len(digits) - 1, -1, -1):\n",
" if digits[i] < 9:\n",
" digits[i] += 1\n",
" return digits\n",
" digits[i] = 0\n",
" \n",
" # 全桁が9の場合\n",
" return [1, *digits]\n",
"```\n",
"\n",
"### LeetCode提出用(最終版)\n",
"\n",
"```python\n",
"class Solution:\n",
" def plusOne(self, digits: list[int]) -> list[int]:\n",
" \"\"\"\n",
" Time Complexity: O(n)\n",
" Space Complexity: O(1) average, O(n) worst case\n",
" \"\"\"\n",
" for i in range(len(digits) - 1, -1, -1):\n",
" if digits[i] < 9:\n",
" digits[i] += 1\n",
" return digits\n",
" digits[i] = 0\n",
" \n",
" return [1, *digits]\n",
"```\n",
"\n",
"## 5. Python特有の最適化ポイント\n",
"\n",
"### CPython インタープリター最適化\n",
"\n",
"1. **組み込みイテレータ活用**\n",
" ```python\n",
" # range()の逆順イテレーションはC実装で高速\n",
" for i in range(len(digits) - 1, -1, -1):\n",
" ```\n",
"\n",
"2. **リスト操作最適化**\n",
" ```python\n",
" # スプレッド演算子によるリスト結合(Python 3.5+)\n",
" return [1, *digits] # [1] + digits より効率的\n",
" ```\n",
"\n",
"3. **早期リターン**\n",
" ```python\n",
" # 不要なループを回避\n",
" if digits[i] < 9:\n",
" digits[i] += 1\n",
" return digits # 即座に終了\n",
" ```\n",
"\n",
"### データ構造選択の根拠\n",
"\n",
"- **`list`を選択**: \n",
" - インデックスアクセスO(1)\n",
" - 末尾追加O(1)\n",
" - CPythonでC実装、高速\n",
" \n",
"- **`deque`不要**: \n",
" - 先頭挿入は最悪ケースのみ(稀)\n",
" - この問題では`list`で十分\n",
"\n",
"### メモリ最適化\n",
"\n",
"1. **in-place変更**: \n",
" - 新規メモリ確保を最小化\n",
" - LeetCode形式では許容される\n",
" \n",
"2. **スプレッド演算子**: \n",
" - `[1] + digits`はコピーが2回発生\n",
" - `[1, *digits]`は1回で効率的\n",
"\n",
"## 6. 実装の特徴と利点\n",
"\n",
"### 型安全性(pylance対応)\n",
"\n",
"```python\n",
"# Python 3.9+の型ヒント\n",
"def plusOne(self, digits: list[int]) -> list[int]:\n",
" # pylanceで完全な型チェックが可能\n",
" # List[int]より list[int] が推奨(PEP 585)\n",
"```\n",
"\n",
"### エッジケース処理\n",
"\n",
"```python\n",
"# テスト例(実装には含めない)\n",
"# [1,2,3] → [1,2,4] 早期リターン\n",
"# [9] → [1,0] 単一要素、全桁9\n",
"# [1,9,9] → [2,0,0] 部分的繰り上がり\n",
"# [9,9,9] → [1,0,0,0] 全桁9、新規配列生成\n",
"```\n",
"\n",
"### パフォーマンス特性\n",
"\n",
"- **平均ケース**: O(1)~O(k) (kは繰り上がり回数)\n",
"- **最悪ケース**: O(n) (全桁が9)\n",
"- **メモリ**: ほぼO(1)、最悪時のみO(n)\n",
"\n",
"この実装は、Pythonの特性を最大限活用し、可読性とパフォーマンスを両立した最適解となっています。"
]
},
{
"cell_type": "markdown",
"id": "d91e2cb0",
"metadata": {},
"source": []
}
],
"metadata": {
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading