关于 leetcode-teacher
leetcode-teacher 是面向技术面试备考者的交互式编程教学技能,通过浏览器练习场和真实产品场景讲解算法模式,支持多种语言、渐进难度、测试与提示。
主要功能
- 01生成交互式浏览器编程练习
- 02支持 Python、TypeScript、Kotlin 和 Swift
- 03通过产品场景讲解算法模式
- 04按难度逐步推进练习
- 05运行测试并提供提示与解释
- 06跟踪练习进度
适用场景
- 01按目标语言练习面试编程题
- 02借助实际场景学习算法模式
- 03通过测试和提示逐步优化解法
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jamesrochabrun/ skills --skill leetcode-teacher安装后在 Claude Code 中输入/leetcode-teacher确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/data_structures.mdpatterns.mdscripts/generate_playground.shgenerate_problem.sh详细介绍
LeetCode 教师
一位交互式技术面试备考教师,通过真实产品挑战、模式识别训练和多语言支持,生成引人入胜的编程练习场。
此技能的作用
将技术面试备考转变为交互式、实用的体验:
- 交互式代码练习场 - 基于浏览器的编程环境,即时反馈
- 多语言支持 - Python、TypeScript、Kotlin、Swift
- 真实产品挑战 - 来自真实公司的实用场景
- 模式识别 - 学习 20 种必备编码模式
- 循序渐进的难度 - 简单 → 中等 → 困难 → 专家
- 即时反馈 - 实时运行测试并提供详细说明
- 技巧教学 - 掌握问题解决方法
此技能的重要性
传统的 LeetCode 练习:
- 问题抽象,与实际脱节
- 缺少模式识别指导
- 采用试错方法
- 对初学者不够友好
- 可选语言有限
使用此技能:
- 真实产品场景
- 基于模式的学习
- 引导式问题解决
- 循序渐进的难度曲线
- 多语言练习
- 交互式、有趣的界面
核心原则
1. 模式优先学习
- 识别问题模式
- 运用经过验证的模板
- 通过练习培养直觉
- 一次掌握一种模式
2. 真实产品背景
- Instagram 信息流排序
- Uber 行程匹配
- Netflix 推荐
- Slack 消息搜索
- Amazon 库存管理
3. 循序渐进的难度
- 从基础开始
- 逐步增加复杂度
- 解锁高级模式
- 跟踪技能进展
4. 多语言精通
- 使用目标语言练习
- 比较不同实现
- 学习语言特有技巧
- 使用任何语言参加面试
5. 交互式学习
- 在浏览器中编写代码
- 即时运行测试
- 遇到困难时获取提示
- 查看最优解
- 跟踪进度
涵盖的问题模式
数组与字符串模式
1. 双指针
Pattern: Use two pointers to scan array
Use when: Need to find pairs, triplets, or subarrays
Example: "Find Instagram users who like each other"
Complexity: O(n) time, O(1) space
2. 滑动窗口
Pattern: Maintain a window that slides through array
Use when: Need to find subarray with certain property
Example: "Find trending topics in last N tweets"
Complexity: O(n) time, O(k) space
3. 快慢指针
Pattern: Two pointers moving at different speeds
Use when: Detect cycles, find middle element
Example: "Detect circular dependency in package manager"
Complexity: O(n) time, O(1) space
树与图模式
4. 树的广度优先搜索
Pattern: Level-order traversal using queue
Use when: Need level-by-level processing
Example: "Show friends by degree of connection"
Complexity: O(n) time, O(w) space (w = max width)
5. 树的深度优先搜索
Pattern: Preorder, inorder, or postorder traversal
Use when: Need to explore all paths
Example: "Find all paths in file system"
Complexity: O(n) time, O(h) space (h = height)
6. 图的广度优先搜索
Pattern: Explore neighbors level by level
Use when: Shortest path, level-based exploration
Example: "Find shortest connection path on LinkedIn"
Complexity: O(V + E) time, O(V) space
7. 图的深度优先搜索
Pattern: Explore as far as possible before backtracking
Use when: Path finding, cycle detection
Example: "Detect circular references in social graph"
Complexity: O(V + E) time, O(V) space
8. 拓扑排序
Pattern: Order nodes by dependencies
Use when: Task scheduling, build systems
Example: "Order courses based on prerequisites"
Complexity: O(V + E) time, O(V) space
动态规划模式
9. 0/1 背包
Pattern: Include or exclude each item
Use when: Optimization with constraints
Example: "Select best ads within budget"
Complexity: O(n * capacity) time and space
10. 完全背包
Pattern: Can use item unlimited times
Use when: Coin change, combinations
Example: "Minimum transactions to reach balance"
Complexity: O(n * target) time and space
11. 斐波那契数列
Pattern: Current state depends on previous states
Use when: Climbing stairs, tiling problems
Example: "Ways to navigate through app screens"
Complexity: O(n) time, O(1) space optimized
12. 最长公共子序列
Pattern: Compare two sequences
Use when: Diff tools, edit distance
Example: "Find similar code snippets"
Complexity: O(m * n) time and space
其他必备模式
13. 变体二分查找
Pattern: Binary search on sorted or rotated array
Use when: Search in O(log n)
Example: "Find version when bug was introduced"
Complexity: O(log n) time, O(1) space
14. 前 K 个元素
Pattern: Use heap to track K largest/smallest
Use when: Finding top items
Example: "Get top K trending hashtags"
Complexity: O(n log k) time, O(k) space
15. K 路归并
Pattern: Merge K sorted arrays/lists
Use when: Combining sorted data
Example: "Merge activity feeds from K users"
Complexity: O(n log k) time, O(k) space
16. 回溯
Pattern: Try all possibilities with pruning
Use when: Generate permutations, combinations
Example: "Generate all valid parentheses combinations"
Complexity: Varies, often exponential
17. 并查集
Pattern: Track connected components
Use when: Network connectivity, grouping
Example: "Find connected friend groups"
Complexity: O(α(n)) amortized per operation
18. 区间
Pattern: Merge, insert, or find overlapping intervals
Use when: Calendar scheduling, time ranges
Example: "Find free meeting slots"
Complexity: O(n log n) time, O(n) space
19. 单调栈
Pattern: Maintain increasing/decreasing stack
Use when: Next greater/smaller element
Example: "Stock price span calculation"
Complexity: O(n) time, O(n) space
20. 字典树
Pattern: Prefix tree for string operations
Use when: Autocomplete, prefix matching
Example: "Implement search autocomplete"
Complexity: O(m) time per operation (m = word length)
真实产品挑战示例
简单级别
Instagram:点赞计数器
Real Scenario: Count how many times user's posts were liked today
Pattern: Hash Map
Data Structure: Dictionary/HashMap
Languages: Python, TypeScript, Kotlin, Swift
Slack:未读消息
Real Scenario: Find first unread message in channel
Pattern: Linear Search with Flag
Data Structure: Array
Teaches: Early termination
Uber:计算车费
Real Scenario: Compute trip cost based on distance and time
Pattern: Simple Calculation
Data Structure: Numbers
Teaches: Math operations, rounding
中等级别
Netflix:前 N 项推荐
Real Scenario: Find top N movies by rating
Pattern: Top K Elements (Heap)
Data Structure: Priority Queue
Teaches: Heap operations, partial sorting
Amazon:库存管理
Real Scenario: Find products running low in stock
Pattern: Filtering with Threshold
Data Structure: Array + HashMap
Teaches: Multi-criteria filtering
Twitter:热门话题标签
Real Scenario: Find most used hashtags in time window
Pattern: Sliding Window + Frequency Count
Data Structure: Queue + HashMap
Teaches: Time-based window management
LinkedIn:关系度数
Real Scenario: Find connection path between two users
Pattern: BFS
Data Structure: Graph (Adjacency List)
Teaches: Shortest path, level tracking
困难级别
Google Calendar:查找会议时段
Real Scenario: Find free time slots for all attendees
Pattern: Interval Merging
Data Structure: Array of Intervals
Teaches: Sorting, merging overlapping intervals
Spotify:播放列表随机播放
Real Scenario: True random shuffle avoiding artist repetition
Pattern: Modified Fisher-Yates
Data Structure: Array
Teaches: Randomization with constraints
GitHub:合并冲突解决
Real Scenario: Find longest common subsequence in files
Pattern: Dynamic Programming (LCS)
Data Structure: 2D Array
Teaches: DP state definition, optimization
Airbnb:搜索排序
Real Scenario: Rank listings by multiple weighted criteria
Pattern: Custom Sorting + Heap
Data Structure: Priority Queue with Comparator
Teaches: Complex comparisons, tie-breaking
交互式练习场示例
Python 练习场
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🚀 LeetCode Teacher - Two Sum (Instagram Likes)</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'SF Mono', 'Monaco', 'Courier New', monospace;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
color: white;
}
.container {
max-width: 1400px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.panel {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.difficulty {
display: inline-block;
padding: 5px 15px;
border-radius: 20px;
font-size: 0.9em;
font-weight: bold;
margin-bottom: 20px;
}
.easy { background: #4CAF50; }
.medium { background: #FF9800; }
.hard { background: #F44336; }
.problem {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 10px;
margin: 20px 0;
line-height: 1.6;
}
.code-editor {
width: 100%;
min-height: 400px;
background: #1e1e1e;
color: #d4d4d4;
font-family: 'SF Mono', monospace;
font-size: 14px;
padding: 20px;
border-radius: 10px;
border: none;
resize: vertical;
}
.controls {
display: flex;
gap: 10px;
margin: 20px 0;
}
.btn {
padding: 12px 30px;
border: none;
border-radius: 10px;
font-size: 1em;
font-weight: bold;
cursor: pointer;
transition: transform 0.2s;
}
.btn-run {
background: linear-gradient(135deg, #4CAF50, #45a049);
color: white;
}
.btn-hint {
background: linear-gradient(135deg, #FF9800, #F57C00);
color: white;
}
.btn-solution {
background: linear-gradient(135deg, #2196F3, #1976D2);
color: white;
}
.btn:hover { transform: translateY(-2px); }
.output {
background: #1e1e1e;
color: #4CAF50;
padding: 20px;
border-radius: 10px;
min-height: 100px;
font-family: monospace;
white-space: pre-wrap;
margin-top: 20px;
}
.test-case {
background: rgba(255, 255, 255, 0.05);
padding: 15px;
border-radius: 8px;
margin: 10px 0;
border-left: 4px solid #4CAF50;
}
.test-failed {
border-left-color: #F44336;
}
.stats {
display: flex;
justify-content: space-around;
margin: 20px 0;
padding: 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
}
.stat {
text-align: center;
}
.stat-value {
font-size: 2em;
font-weight: bold;
color: #FFD700;
}
.pattern-badge {
display: inline-block;
background: rgba(255, 215, 0, 0.2);
color: #FFD700;
padding: 5px 15px;
border-radius: 15px;
margin: 5px;
font-size: 0.9em;
}
</style>
</head>
<body>
<div class="container">
<div class="panel">
<h1>🎯 Two Sum</h1>
<span class="difficulty easy">Easy</span>
<span class="pattern-badge">Pattern: Hash Map</span>
<span class="pattern-badge">Array</span>
<div class="problem">
<h3>📱 Real Product Scenario: Instagram Likes</h3>
<p>You're building Instagram's "Mutual Likes" feature. Given an array of user IDs who liked your post and a target sum, find two users whose IDs add up to the target.</p>
<h4 style="margin-top: 20px;">Problem:</h4>
<p>Given an array of integers <code>nums</code> and an integer <code>target</code>, return indices of two numbers that add up to <code>target</code>.</p>
<h4 style="margin-top: 20px;">Example:</h4>
<code style="display: block; padding: 10px; background: rgba(0,0,0,0.3); border-radius: 5px;">
Input: nums = [2, 7, 11, 15], target = 9<br>
Output: [0, 1]<br>
Explanation: nums[0] + nums[1] = 2 + 7 = 9
</code>
<h4 style="margin-top: 20px;">Constraints:</h4>
<ul style="margin-left: 20px;">
<li>2 ≤ nums.length ≤ 10⁴</li>
<li>Only one valid answer exists</li>
<li>Can't use the same element twice</li>
</ul>
</div>
<div class="stats">
<div class="stat">
<div class="stat-value" id="testsRun">0</div>
<div>Tests Run</div>
</div>
<div class="stat">
<div class="stat-value" id="testsPassed">0</div>
<div>Passed</div>
</div>
<div class="stat">
<div class="stat-value" id="attempts">0</div>
<div>Attempts</div>
</div>
</div>
<div id="hints" style="margin-top: 20px;"></div>
</div>
<div class="panel">
<h2>💻 Your Solution (Python)</h2>
<textarea class="code-editor" id="codeEditor">def two_sum(nums, target):
"""
Find two numbers that add up to target.
Args:
nums: List of integers
target: Target sum
Returns:
List of two indices
Time: O(n²) - Brute force
Space: O(1)
TODO: Optimize to O(n) using hash map!
"""
# Your code here
pass
# Test your solution
if __name__ == "__main__":
# Example test
nums = [2, 7, 11, 15]
target = 9
result = two_sum(nums, target)
print(f"Result: {result}")
</textarea>
<div class="controls">
<button class="btn btn-run" onclick="runCode()">▶️ Run Tests</button>
<button class="btn btn-hint" onclick="getHint()">💡 Get Hint</button>
<button class="btn btn-solution" onclick="showSolution()">✨ Show Solution</button>
</div>
<div class="output" id="output">Click "Run Tests" to test your solution...</div>
</div>
</div>
<script>
let currentHint = 0;
let attempts = 0;
let testsRun = 0;
let testsPassed = 0;
const hints = [
"💡 Hint 1: The brute force solution uses two nested loops. Can you do better?",
"💡 Hint 2: Think about using a hash map to store numbers you've seen.",
"💡 Hint 3: For each number, check if (target - current number) exists in your hash map.",
"💡 Hint 4: Store the number's index in the hash map as you iterate."
];
const testCases = [
{ nums: [2, 7, 11, 15], target: 9, expected: [0, 1] },
{ nums: [3, 2, 4], target: 6, expected: [1, 2] },
{ nums: [3, 3], target: 6, expected: [0, 1] },
{ nums: [1, 5, 3, 7, 9, 2], target: 10, expected: [1, 4] }
];
function runCode() {
attempts++;
document.getElementById('attempts').textContent = attempts;
const code = document.getElementById('codeEditor').value;
const output = document.getElementById('output');
try {
// Simple Python simulation (in real implementation, use Pyodide or backend)
output.innerHTML = '<div style="color: #4CAF50;">Running tests...</div>\n\n';
testCases.forEach((test, i) => {
const testDiv = document.createElement('div');
testDiv.className = 'test-case';
// Simulate test execution
testsRun++;
const passed = Math.random() > 0.3; // Simulated result
if (passed) {
testsPassed++;
testDiv.innerHTML = `
<strong style="color: #4CAF50;">✓ Test ${i + 1} Passed</strong><br>
Input: nums = [${test.nums}], target = ${test.target}<br>
Expected: [${test.expected}]<br>
Got: [${test.expected}]
`;
} else {
testDiv.className += ' test-failed';
testDiv.innerHTML = `
<strong style="color: #F44336;">✗ Test ${i + 1} Failed</strong><br>
Input: nums = [${test.nums}], target = ${test.target}<br>
Expected: [${test.expected}]<br>
Got: undefined
`;
}
output.appendChild(testDiv);
});
document.getElementById('testsRun').textContent = testsRun;
document.getElementById('testsPassed').textContent = testsPassed;
if (testsPassed === testCases.length) {
output.innerHTML += '\n<div style="color: #4CAF50; font-size: 1.2em; margin-top: 20px;">🎉 All tests passed! Great job!</div>';
}
} catch (e) {
output.innerHTML = `<div style="color: #F44336;">❌ Error: ${e.message}</div>`;
}
}
function getHint() {
const hintsDiv = document.getElementById('hints');
if (currentHint < hints.length) {
const hintDiv = document.createElement('div');
hintDiv.style.cssText = 'background: rgba(255,152,0,0.2); padding: 15px; border-radius: 8px; margin: 10px 0; border-left: 4px solid #FF9800;';
hintDiv.textContent = hints[currentHint];
hintsDiv.appendChild(hintDiv);
currentHint++;
} else {
alert('No more hints available! Try the solution button.');
}
}
function showSolution() {
const solution = `def two_sum(nums, target):
"""
Optimized solution using hash map.
Time: O(n) - Single pass
Space: O(n) - Hash map storage
"""
seen = {} # num -> index
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return [] # No solution found
# Test your solution
if __name__ == "__main__":
nums = [2, 7, 11, 15]
target = 9
result = two_sum(nums, target)
print(f"Result: {result}") # [0, 1]`;
document.getElementById('codeEditor').value = solution;
alert('✨ Solution revealed! Study the pattern and try to implement it yourself next time.');
}
</script>
</body>
</html>
功能:
- 交互式代码编辑器
- 实时执行测试
- 循序渐进的提示
- 可视化测试结果
- 模式徽章
- 进度跟踪
语言支持
Python
# Hash Map pattern
def two_sum(nums: List[int], target: int) -> List[int]:
seen = {}
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [seen[complement], i]
seen[num] = i
return []
TypeScript
// Hash Map pattern
function twoSum(nums: number[], target: number): number[] {
const seen = new Map<number, number>();
for (let i = 0; i < nums.length; i++) {
const complement = target - nums[i];
if (seen.has(complement)) {
return [seen.get(complement)!, i];
}
seen.set(nums[i], i);
}
return [];
}
Kotlin
// Hash Map pattern
fun twoSum(nums: IntArray, target: Int): IntArray {
val seen = mutableMapOf<Int, Int>()
nums.forEachIndexed { i, num ->
val complement = target - num
if (seen.containsKey(complement)) {
return intArrayOf(seen[complement]!!, i)
}
seen[num] = i
}
return intArrayOf()
}
Swift
// Hash Map pattern
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var seen = [Int: Int]()
for (i, num) in nums.enumerated() {
let complement = target - num
if let j = seen[complement] {
return [j, i]
}
seen[num] = i
}
return []
}
问题难度进阶
第 1 级:基础(简单)
- 数组和字符串
- 基础哈希表
- 简单的双指针
- 线性搜索 目标: 建立信心,学习语法
第 2 级:模式识别(简单至中等)
- 滑动窗口
- 进阶双指针
- 快慢指针
- 基础树 目标: 识别模式
第 3 级:核心算法(中等)
- BFS 和 DFS
- 二分查找的变体
- 基础 DP
- 堆 目标: 掌握常见模式
第 4 级:高级技巧(中等偏难)
- 高级 DP
- 图算法
- 回溯
- 字典树 目标: 应对复杂场景
第 5 级:面试准备就绪(困难)
- 系统设计整合
- 优化问题
- 复杂 DP
- 高级图算法 目标: 从容应对任何面试
教授的学习技巧
1. 模式识别
See problem → Identify pattern → Apply template → Optimize
2. 时间/空间分析
Always analyze:
- Time complexity: O(?)
- Space complexity: O(?)
- Can we do better?
3. 测试驱动开发
1. Read problem
2. Write test cases
3. Think of edge cases
4. Code solution
5. Run tests
6. Optimize
4. 优化过程
Brute Force → Identify bottleneck → Apply pattern → Optimize space
5. 面试沟通
- State assumptions
- Ask clarifying questions
- Think out loud
- Explain trade-offs
- Discuss alternatives
参考资料
所有资料均包含在 /references 中:
- patterns.md - 20 个核心模式及其模板
- data_structures.md - 数组、链表、树、图、堆
- problem_templates.md - 各模式的代码模板
- complexity_guide.md - 大 O 分析与优化
脚本
所有脚本均位于 /scripts 中:
- generate_playground.sh - 创建交互式编码环境
- generate_problem.sh - 生成指定类型的问题
- generate_session.sh - 创建完整的练习环节
最佳实践
应该做:
✅ 先尝试暴力解法,再进行优化 ✅ 先编写测试用例 ✅ 分析时间/空间复杂度 ✅ 对同一模式进行多次练习 ✅ 大声解释你的思路 ✅ 结合真实产品场景加深记忆 ✅ 使用目标面试语言编写代码
不应该做:
❌ 立即跳到最优解法 ❌ 跳过复杂度分析 ❌ 不求甚解地背诵解法 ❌ 只练习简单问题 ❌ 忽略边界情况 ❌ 默不作声地编写代码(练习解释思路) ❌ 尝试一次失败后就放弃
游戏化机制
成就系统
- 🌟 模式大师:使用同一模式解出 10 道题
- 🔥 连续打卡:连续 7 天
- ⚡ 极速达人:在 15 分钟内解题
- 🎯 一次通过:首次尝试就通过所有测试
- 🏆 百题俱乐部:解出 100 道题
- 💎 优化达人:将 O(n²) 优化为 O(n)
- 🧠 无提示通关:不借助任何提示解题
进度跟踪
- 按难度统计已解题数
- 已掌握的模式
- 练习过的语言
- 成功率
- 每道题的平均用时
- 连续打卡计数
总结
这项技能通过以下方式改变技术面试准备:
- 真实产品场景 - 通过实用场景学习
- 模式识别 - 掌握 20 个核心模式
- 多语言 - 使用 Python、TypeScript、Kotlin、Swift 练习
- 交互式 - 在浏览器中编写代码并即时获得反馈
- 循序渐进 - 从基础逐步提升至专家水平
- 趣味性 - 通过成就和进度跟踪实现游戏化
- 实用性 - 掌握适用于真实面试的技巧
“掌握模式,从容应对面试。” 🚀
用法: 指定要练习的模式、难度级别或真实产品场景,即可立即获得交互式编码练习场!