Skip to content

Commit 8e32553

Browse files
authored
Merge pull request #237 from myoshi2891/dev-from-macmini
docs(2619): fix Mermaid diagram syntax and improve dark mode readability
2 parents af5e1da + 2ee6298 commit 8e32553

4 files changed

Lines changed: 2323 additions & 0 deletions

File tree

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "2e9e29f3",
6+
"metadata": {},
7+
"source": [
8+
"# 1. 問題の分析\n",
9+
"\n",
10+
"## 競技プログラミング視点での分析\n",
11+
"- **速度最優先アプローチ**: 配列の長さを取得し、最後の要素にO(1)でアクセス\n",
12+
"- **メモリ最小化方針**: 追加のメモリ不要、インデックスアクセスのみ使用\n",
13+
"- **計算量**: O(1) 時間、O(1) 空間\n",
14+
"\n",
15+
"## 業務開発視点での分析\n",
16+
"- **保守性・可読性アプローチ**: シンプルな条件分岐で空配列と非空配列を区別\n",
17+
"- **エラーハンドリング**: `JSON.parse`の出力が前提のため、基本的な型チェックは不要\n",
18+
"- **プロトタイプ拡張**: `Array.prototype`への追加は慎重に行うべきだが、問題要件として明示されている\n",
19+
"\n",
20+
"## JavaScript特有の考慮点\n",
21+
"- **V8最適化**: \n",
22+
" - `length`プロパティアクセスは最適化済み\n",
23+
" - インデックスアクセス `arr[index]` は最速\n",
24+
" - 条件分岐は予測可能なパターンで高速化\n",
25+
"- **GC対策**: \n",
26+
" - 新規オブジェクト生成なし\n",
27+
" - クロージャなし\n",
28+
"- **配列操作特性**: \n",
29+
" - `arr[arr.length - 1]` は `arr.at(-1)` より広くサポートされ、同等に高速\n",
30+
" - 空配列チェックは `length === 0` が最も明示的\n",
31+
"\n",
32+
"# 2. アルゴリズムアプローチ比較\n",
33+
"\n",
34+
"| アプローチ | 時間計算量 | 空間計算量 | JS実装コスト | 可読性 | 備考 |\n",
35+
"|----------|----------|----------|------------|-------|------|\n",
36+
"| インデックス直接アクセス | O(1) | O(1) | 低 | 高 | `arr[length-1]`、最速 |\n",
37+
"| at()メソッド使用 | O(1) | O(1) | 低 | 高 | ES2022、互換性に注意 |\n",
38+
"| pop() + push() | O(1) | O(1) | 中 | 低 | 破壊的、非推奨 |\n",
39+
"\n",
40+
"注: 「JS実装コスト」は互換性・型安定性・関数呼び出しコスト込みで評価。\n",
41+
"\n",
42+
"# 3. 選択したアルゴリズムと理由\n",
43+
"\n",
44+
"- **選択したアプローチ**: インデックス直接アクセス\n",
45+
"- **理由**:\n",
46+
" - **計算量**: O(1)で最適\n",
47+
" - **JS実装効率**: V8エンジンで最も最適化されたパターン\n",
48+
" - **保守性**: 明示的な条件分岐で意図が明確\n",
49+
" - **互換性**: すべてのJavaScript環境で動作\n",
50+
"- **JavaScript特有の最適化ポイント**:\n",
51+
" - `this.length` の一度だけの参照で JIT最適化を促進\n",
52+
" - 三項演算子による分岐予測の最適化\n",
53+
" - プリミティブ値のみの操作でGC負荷ゼロ\n",
54+
"\n",
55+
"# 4. コード実装(solution.js)\n",
56+
"\n",
57+
"Analyze Complexity\n",
58+
"Runtime 52 ms\n",
59+
"Beats 12.22%\n",
60+
"Memory 53.31 MB\n",
61+
"Beats 78.39%\n",
62+
"\n",
63+
"```javascript\n",
64+
"'use strict';\n",
65+
"\n",
66+
"/**\n",
67+
" * Returns the last element of the array, or -1 if the array is empty.\n",
68+
" * \n",
69+
" * @return {null|boolean|number|string|Array|Object} The last element or -1\n",
70+
" * \n",
71+
" * Time Complexity: O(1)\n",
72+
" * Space Complexity: O(1)\n",
73+
" * \n",
74+
" * @example\n",
75+
" * const arr = [1, 2, 3];\n",
76+
" * arr.last(); // 3\n",
77+
" * \n",
78+
" * @example\n",
79+
" * const empty = [];\n",
80+
" * empty.last(); // -1\n",
81+
" */\n",
82+
"Array.prototype.last = function() {\n",
83+
" // 空配列チェック: length が 0 なら -1 を返す\n",
84+
" // それ以外は最後の要素 (this[this.length - 1]) を返す\n",
85+
" return this.length === 0 ? -1 : this[this.length - 1];\n",
86+
"};\n",
87+
"\n",
88+
"// LeetCode形式ではmodule.exportsは不要ですが、テスト用に残す場合:\n",
89+
"// module.exports = { Array };\n",
90+
"```\n",
91+
"\n",
92+
"# 5. 追加メモ(JS最適化チェックリスト)\n",
93+
"\n",
94+
"✅ **実装済みの最適化**:\n",
95+
"- `this.length` を直接参照(インライン化可能)\n",
96+
"- インデックスアクセス `this[index]` 使用(最速パス)\n",
97+
"- 三項演算子で分岐最小化(予測可能)\n",
98+
"- 新規オブジェクト/配列生成ゼロ\n",
99+
"- クロージャなし\n",
100+
"- プリミティブ演算のみ(GC負荷なし)\n",
101+
"\n",
102+
"✅ **LeetCode要件への適合**:\n",
103+
"- `Array.prototype` への正しい追加\n",
104+
"- 空配列で `-1` を返す仕様を満たす\n",
105+
"- JSON値(null, boolean, number, string, Array, Object)すべてに対応\n",
106+
"- 制約 `0 <= arr.length <= 1000` を満たす(上限チェック不要)\n",
107+
"\n",
108+
"**注意点**:\n",
109+
"- 実務では `Array.prototype` の拡張は避けるべき(ネイティブメソッドとの衝突リスク)\n",
110+
"- この問題は学習目的であり、プロトタイプ拡張の仕組みを理解するためのもの\n",
111+
"\n",
112+
"# パフォーマンス分析と改善案\n",
113+
"\n",
114+
"現在の結果:\n",
115+
"- **Runtime: 52ms (Beats 12.22%)** ← 改善の余地あり\n",
116+
"- **Memory: 53.31MB (Beats 78.39%)** ← 良好\n",
117+
"\n",
118+
"## 問題点の分析\n",
119+
"\n",
120+
"Runtime が遅い原因として考えられる点:\n",
121+
"1. **三項演算子の分岐コスト**: わずかだがオーバーヘッドが存在\n",
122+
"2. **length プロパティの複数回アクセス**: 最適化されていても微小なコスト\n",
123+
"3. **厳格モード ('use strict')**: LeetCode環境では不要\n",
124+
"\n",
125+
"## 改善戦略\n",
126+
"\n",
127+
"### アプローチ1: 極限まで単純化\n",
128+
"```javascript\n",
129+
"Array.prototype.last = function() {\n",
130+
" return this.length ? this[this.length - 1] : -1;\n",
131+
"};\n",
132+
"```\n",
133+
"\n",
134+
"### アプローチ2: length キャッシュ(理論上は不要だが試す価値あり)\n",
135+
"```javascript\n",
136+
"Array.prototype.last = function() {\n",
137+
" const len = this.length;\n",
138+
" return len ? this[len - 1] : -1;\n",
139+
"};\n",
140+
"```\n",
141+
"\n",
142+
"### アプローチ3: 最も短く(V8の最適化に任せる)\n",
143+
"```javascript\n",
144+
"Array.prototype.last = function() {\n",
145+
" return this[this.length - 1] ?? -1;\n",
146+
"};\n",
147+
"```\n",
148+
"\n",
149+
"## 推奨実装\n",
150+
"\n",
151+
"Analyze Complexity\n",
152+
"Runtime 40 ms\n",
153+
"Beats 74.20%\n",
154+
"Memory 53.71 MB\n",
155+
"Beats 53.97%\n",
156+
"\n",
157+
"```javascript\n",
158+
"/**\n",
159+
" * Returns the last element of the array, or -1 if the array is empty.\n",
160+
" * \n",
161+
" * @return {null|boolean|number|string|Array|Object} The last element or -1\n",
162+
" * \n",
163+
" * Time Complexity: O(1)\n",
164+
" * Space Complexity: O(1)\n",
165+
" */\n",
166+
"Array.prototype.last = function() {\n",
167+
" return this.length ? this[this.length - 1] : -1;\n",
168+
"};\n",
169+
"```\n",
170+
"\n",
171+
"## 変更点と理由\n",
172+
"\n",
173+
"1. **`=== 0` → truthyチェック**: \n",
174+
" - `this.length` が 0 なら falsy、それ以外は truthy\n",
175+
" - 比較演算子のコストを削減\n",
176+
"\n",
177+
"2. **JSDoc簡略化**:\n",
178+
" - LeetCode環境ではコメントも実行時間に影響する可能性\n",
179+
" - 必要最小限に\n",
180+
"\n",
181+
"3. **'use strict' 削除**:\n",
182+
" - LeetCodeではグローバルスコープで実行されるため不要\n",
183+
"\n",
184+
"## さらなる最適化(試験的)\n",
185+
"\n",
186+
"もし Nullish coalescing (`??`) が LeetCode 環境でサポートされていれば:\n",
187+
"\n",
188+
"```javascript\n",
189+
"Array.prototype.last = function() {\n",
190+
" return this[this.length - 1] ?? -1;\n",
191+
"};\n",
192+
"```\n",
193+
"\n",
194+
"**注意**: この方法は `undefined` と `-1` を同一視するため、配列の最後が `undefined` の場合に `-1` を返します。ただし問題文では「JSON.parseの出力」が前提なので、`undefined` は含まれません(JSONには`undefined`が存在しない)。\n",
195+
"\n",
196+
"## 最終推奨コード\n",
197+
"\n",
198+
"Analyze Complexity\n",
199+
"Runtime 40 ms\n",
200+
"Beats 74.20%\n",
201+
"Memory 52.94 MB\n",
202+
"Beats 90.58%\n",
203+
"\n",
204+
"```javascript\n",
205+
"Array.prototype.last = function() {\n",
206+
" return this.length ? this[this.length - 1] : -1;\n",
207+
"};\n",
208+
"```\n",
209+
"\n",
210+
"この実装で **Runtime が 20-30% 改善**される可能性があります。LeetCode のベンチマークは実行ごとに変動するため、複数回提出して最良の結果を確認することをお勧めします。"
211+
]
212+
}
213+
],
214+
"metadata": {
215+
"language_info": {
216+
"name": "python"
217+
}
218+
},
219+
"nbformat": 4,
220+
"nbformat_minor": 5
221+
}

0 commit comments

Comments
 (0)