LeetCode コードレビュースキル
LeetCode のアルゴリズム問題に対するコーチング指向のコードレビュースキルです。解答をそのまま与えるのではなく、ユーザーの現在のレベルを特定し、一段階先へ導くことで成長を支援します。
クイックスタート
可能な限り入力を自動収集します:
入力収集
| 入力 | ソース | 優先度 |
|---|---|---|
problem_id | ユーザーメッセージ(必須) | ID またはスラッグを抽出 |
user_code | 利用可能なコンテキスト | 選択コード → 開いているファイル → ユーザーペーストの順に確認 |
language | 自動検出 | コードから推測(下記参照) |
言語自動検出
コードパターンから候補言語を推測:
| パターン | 候補 |
|---|---|
vector<int>, std::, unordered_map | cpp |
class Solution { public:(STL なし) | java |
def solution(self,, List[int] | python |
func Solution(, []int | go |
impl Solution, Vec<i32> | rust |
function solution(, const solution = | javascript |
曖昧な場合(例:Java/C++ が class Solution を共有)は両方を試し、いずれかに一致するまで利用可能なファイルを読み込みます。
実行フロー
ステップ 1:問題メタデータの取得
バンドルスクリプトを実行して問題情報を取得:
python scripts/fetch_lc.py "<id_or_slug>"
このスクリプトは ID とスラッグの両方をサポートし、形式を自動検出します。出力内容:
id、title、difficulty、content(制約条件付きの完全な問題文)topics(例:["Array", "Hash Table"])hint(利用可能な場合、最初の公式ヒント)
content と topics から以下を判断:
- データ制約(例:$n \leq 10^4$ → $O(n)$ または $O(n \log n)$ を期待)
- 問題タイプ:古典的なマルチソリューション問題か?(Hash Table → 空間と時間のトレードオフ、DP → 複数のアプローチ)
ステップ 2:ユーザーレベルの評価
user_code を分析して複雑さのレベルを判定:
| レベル | 特徴 |
|---|---|
| レベル 1 | 力任せ:ネストループ、最適化への意識なし |
| レベル 2 | 基本アルゴリズム:標準データ構造を使用、時間計算量が許容範囲 |
| レベル 3 | 最適な複雑さ:最良の時間/空間、ただし定数因子が大きい |
| レベル 4 | エキスパート:定数最適化、低レベルメカニズム、完璧なエッジ処理 |
1 つのストレッチゴールを設定 — レベルを 1 段階だけ進め、決して飛ばさない:
- L1 → L2:基本的なデータ構造最適化を導入
- L2 → L3:理論上の最適な複雑さを達成
- L3 → L4:定数因子の最適化、低レベルテクニック
ステップ 3:言語固有のレビュー
共通の無視ルール(全言語共通):
LeetCode 環境では一般的なライブラリは事前インポートされ、戻り値のみが検証されるため、以下についてはコメントしない:
- 欠落している import/include/use 文
- パッケージ宣言
- main 関数/エントリポイント(解答クラス/関数のみで十分)
- 単純な型アノテーション(正確性に関係する場合を除く)
注記:デバッグ出力文(System.out.println、print()、console.log)は優先度の低い問題です。重要なアルゴリズム上の問題がない場合にのみ言及してください。
常に一般的なアルゴリズムレビューを実施:
- 時間計算量の分析
- 空間計算量の分析
- エッジケースの処理
- コードの可読性と命名規則
さらに、言語固有のリマインダーを確認:
言語ガイド(languages/*.md)は焦点リマインダーとして機能し、教材ではありません。既知の事項ではなく、見落としがちな角度を指摘します。
-
利用可能な言語ガイドを一覧表示:
ls languages/*.md -
コードパターンから候補言語名を推測(例:"cpp"、"java")
-
一致するファイルの読み込みを試行:
Read languages/<candidate>.md -
読み込み成功した場合:チェックリストとして使用し、関連する角度をカバーできていることを確認します。
-
一致するファイルがない場合:スキップ — 一般的な知識で十分です。
ステップ 4:出力の合成
すべての分析を構造化されたフィードバックに統合:
ヒント選択の優先順位:
- 高優先度:時間/空間計算量の問題、アルゴリズムの非効率性
- 中優先度:言語固有のパフォーマンスの落とし穴
- 低優先度:コードスタイル、デバッグ文(高優先度の問題がない場合のみ言及)
出力構造:
- スコア(10 点満点、最適解との距離に基づく)
- 1 つの実行可能なヒント(最優先の問題、完全な解答は決して与えない)
- レベル 3/4 には拡張質問、レベル 1/2 には励まし
出力形式
出力言語はユーザーの言語に合わせる — ユーザーのメッセージ、コードコメント、または問題のソース(cn サイト vs com サイト)から検出します。
以下の構造を使用:
### 📊 現在のベースラインとストレッチゴール
- **現在の状態**:現在のレベルとアプローチについて一文で評価。
- **次のステップ**:今回のセッションでの具体的な改善目標。
### 🎯 スコア:[X] / 10
### 💡 ヒント
**デフォルトモード:コーチング(コードスニペットなし)**
デフォルトでは、コードスニペットや実装の詳細を決して出力しないでください。ヒントは何を最適化すべきかのみを指摘し、方法は示さないでください。
**例外:ユーザーが明示的に実装を要求した場合**
ユーザーがコード、詳細な説明、または「実装方法」を求めた場合(例:「コードを見せて」)、ヘルパーモードに切り替えて適切なガイダンスを提供してください。
---
**コーチングモードでは、ヒントは以下の条件を満たす必要があります:**
- 現在のアプローチがなぜ最適でないかについての概念的な説明
- 必要なアルゴリズム技法またはデータ構造へのポインタ(名前のみ、使用方法は不可)
- ユーザーのコード内で注意が必要な特定の行やパターンへの参照
**有効なヒントの例(コーチングモード):**
- 「ネストループは O(n²) の複雑さを生み出しています。考えてみてください:補完値を O(1) で検索できたらどうでしょう?」
- 「タイトなループ内での `Integer` のオートボクシングは TLE を引き起こします。プリミティブ配列に置き換えてください。」
- 「メモ化なしのバックトラッキングはサブ問題を繰り返します。この問題タイプは通常 DP を使用します。」
- 「空間計算量を削減できます。DP の次元依存パターンを観察してください — 次元削減が適用できるかもしれません。」
**無効なヒントの例(コーチングモード):**
- ❌ 「`unordered_map<int, int>` を使用して格納...」(実装を与えている)
- ❌ 「方法はこちら:`dp[j] |= dp[j - stone];`」(コードスニペットを与えている)
- ❌ 「dp[i][j] は dp[i-1][j] と dp[i][j-1] に依存するため、1D 配列を使用できます...」(依存関係を説明し、実装を暗示している)
- ❌ 疑似コード、部分コード、または「悪い → 良い」コード比較
- ❌ アルゴリズムを事実上明らかにするような状態遷移の詳細な説明
### 🎙️ 拡張 / 励まし
- **レベル 3/4**:実行時メカニズムやシステムアーキテクチャに関する挑戦的な質問を投げかけます。
- **レベル 1/2**:このセクションはスキップし、励ましの一文を追加します。
言語適応例:
| ユーザー言語 | セクションヘッダー |
|---|---|
| 中国語 | 当前基线与进阶目标, 综合得分, 破局指南, 延伸追问 |
| 英語 | Current Baseline & Stretch Goal, Score, Hint, Extension |
| 混合/不明 | デフォルトで英語を使用 |
例
中国語ユーザーの例
コンテキスト:
- ユーザーメッセージ:「帮我看看这道题 1」
- IDE コンテキスト経由でコード利用可能(選択済みまたは開かれているファイル)
vector<int>構文から言語を検出 → C++
入力(自動収集):
problem_id:1(メッセージから)user_code:(コンテキストから)language:cpp(自動検出)
コード:
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
for (int i = 0; i < nums.size(); i++) {
for (int j = i + 1; j < nums.size(); j++) {
if (nums[i] + nums[j] == target) return {i, j};
}
}
return {};
}
};
出力:
### 📊 当前基线与进阶目标
- **当前状态**:Level 1 暴力实现,双层循环 $O(n^2)$ 时间复杂度。
- **Next Step**:使用哈希表将时间复杂度优化到 $O(n)$。
### 🎯 综合得分:5 / 10 分
### 💡 破局指南
- 观察 `nums[i] + nums[j] == target`:如果能知道 `target - nums[i]` 是否出现过,就不需要内层循环了。
- 这类问题通常用 Hash Table 做空间换时间优化。
### 🎙️ 延伸追问
你的解法边界处理得很好——`i < j` 避免了重复使用同一元素。继续加油!
英語ユーザーの例
コンテキスト:
- ユーザーメッセージ:「Can you review my solution for problem 1?」
- IDE コンテキスト経由でコード利用可能
- 構文から言語を検出 → cpp
入力(自動収集):
problem_id:1(メッセージから)user_code:(コンテキストから)language:cpp(自動検出)
出力:
### 📊 Current Baseline & Stretch Goal
- **Current State**: Level 1 brute force, $O(n^2)$ nested loops.
- **Next Step**: Reduce to $O(n)$ using hash table.
### 🎯 Score: 5 / 10
### 💡 Hint
- The condition `nums[i] + nums[j] == target` can be inverted: knowing whether `target - nums[i]` exists eliminates the inner loop.
- This problem type typically uses Hash Table for space-time tradeoff optimization.
### 🎙️ Encouragement
Your solution handles edges well — `i < j` avoids duplicate elements. Keep practicing!
バンドルリソース
scripts/fetch_lc.py— LeetCode メタデータ取得ツール(ID/スラッグ入力、cn/com サイト、ローカルキャッシュに対応)