mcpField
L
leetcode-teacher

leetcode-teacher

github.com/jamesrochabrun开发221594 次安装41 周前更新
代码仓库

关于 leetcode-teacher

leetcode-teacher 是面向技术面试备考者的交互式编程教学技能,通过浏览器练习场和真实产品场景讲解算法模式,支持多种语言、渐进难度、测试与提示。

主要功能

  1. 01生成交互式浏览器编程练习
  2. 02支持 Python、TypeScript、Kotlin 和 Swift
  3. 03通过产品场景讲解算法模式
  4. 04按难度逐步推进练习
  5. 05运行测试并提供提示与解释
  6. 06跟踪练习进度

适用场景

  1. 01按目标语言练习面试编程题
  2. 02借助实际场景学习算法模式
  3. 03通过测试和提示逐步优化解法

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jamesrochabrun/skills --skill leetcode-teacher

安装后在 Claude Code 中输入/leetcode-teacher确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
data_structures.md
patterns.md
scripts/
generate_playground.sh
generate_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 练习
  • 交互式 - 在浏览器中编写代码并即时获得反馈
  • 循序渐进 - 从基础逐步提升至专家水平
  • 趣味性 - 通过成就和进度跟踪实现游戏化
  • 实用性 - 掌握适用于真实面试的技巧

“掌握模式,从容应对面试。” 🚀


用法: 指定要练习的模式、难度级别或真实产品场景,即可立即获得交互式编码练习场!

评论

支持 Markdown