LeetCode技术面试导师Skill leetcode-teacher

LeetCode技术面试导师是一个交互式在线教育技能,专为技术面试准备设计。它通过真实产品场景教学20个核心编码模式,支持Python、TypeScript、Kotlin和Swift等多种编程语言,提供从易到难的渐进式训练,并配备即时反馈和模式识别指导。帮助用户掌握数据结构和算法,提升编码能力和面试成功率。关键词:技术面试准备, LeetCode练习, 编码模式, 算法学习, 在线编程教育, 数据结构, 多语言支持, 交互式学习, 渐进式难度, 真实产品挑战。

在线教育 0 次安装 0 次浏览 更新于 3/17/2026

名称: leetcode-教师 描述: 交互式LeetCode风格教师,用于技术面试准备。生成带有真实产品挑战的编码游乐场,教学模式和技巧,支持Python/TypeScript/Kotlin/Swift,并提供数据结构和算法的渐进式难度训练。

LeetCode教师

一个交互式技术面试准备教师,生成带有真实世界产品挑战的参与性编码游乐场、模式识别训练和多语言支持。

此技能功能

将技术面试准备转化为交互式、实践经验:

  • 交互式代码游乐场 - 浏览器基础的编码环境,提供即时反馈
  • 多语言支持 - Python, TypeScript, Kotlin, Swift
  • 真实产品挑战 - 来自真实公司的实用场景
  • 模式识别 - 学习20个基本编码模式
  • 渐进式难度 - 简单 → 中等 → 困难 → 专家
  • 即时反馈 - 实时运行测试并附带详细解释
  • 技巧教学 - 掌握问题解决方法

为何此技能重要

传统LeetCode练习:

  • 抽象、不连贯的问题
  • 无模式识别指导
  • 试错方法
  • 对初学者吓人
  • 语言选项有限

使用此技能:

  • 真实产品场景
  • 基于模式的学习
  • 引导式问题解决
  • 渐进式难度曲线
  • 多语言练习
  • 交互式、有趣界面

核心原则

1. 模式优先学习

  • 识别问题模式
  • 应用已验证模板
  • 通过练习建立直觉
  • 一次掌握一个模式

2. 真实产品上下文

  • Instagram动态排名
  • Uber行程匹配
  • Netflix推荐
  • Slack消息搜索
  • Amazon库存管理

3. 渐进式难度

  • 从基础开始
  • 逐步构建复杂性
  • 解锁高级模式
  • 跟踪技能进展

4. 多语言掌握

  • 用目标语言练习
  • 比较实现
  • 学习语言特定技巧
  • 用任何语言面试

5. 交互式学习

  • 在浏览器中编写代码
  • 即时运行测试
  • 卡住时获取提示
  • 查看最优解决方案
  • 跟踪进度

覆盖的问题模式

数组和字符串模式

1. 双指针

模式: 使用两个指针扫描数组
使用时机: 需要找到对、三元组或子数组
示例: “找到Instagram上互相喜欢的用户”
复杂度: O(n) 时间, O(1) 空间

2. 滑动窗口

模式: 维护一个滑动穿过数组的窗口
使用时机: 需要找到具有特定属性的子数组
示例: “找到最后N条推文中的热门话题”
复杂度: O(n) 时间, O(k) 空间

3. 快慢指针

模式: 以不同速度移动的两个指针
使用时机: 检测循环, 找到中间元素
示例: “检测包管理器中的循环依赖”
复杂度: O(n) 时间, O(1) 空间

树和图模式

4. 树广度优先搜索

模式: 使用队列进行层序遍历
使用时机: 需要逐层处理
示例: “按连接度显示朋友”
复杂度: O(n) 时间, O(w) 空间 (w = 最大宽度)

5. 树深度优先搜索

模式: 前序、中序或后序遍历
使用时机: 需要探索所有路径
示例: “找到文件系统中的所有路径”
复杂度: O(n) 时间, O(h) 空间 (h = 高度)

6. 图广度优先搜索

模式: 逐层探索邻居
使用时机: 最短路径, 基于层的探索
示例: “在LinkedIn上找到最短连接路径”
复杂度: O(V + E) 时间, O(V) 空间

7. 图深度优先搜索

模式: 尽可能深入探索再回溯
使用时机: 路径查找, 循环检测
示例: “在社交图中检测循环引用”
复杂度: O(V + E) 时间, O(V) 空间

8. 拓扑排序

模式: 按依赖关系排序节点
使用时机: 任务调度, 构建系统
示例: “基于先决条件排序课程”
复杂度: O(V + E) 时间, O(V) 空间

动态规划模式

9. 0/1背包问题

模式: 包含或排除每个项目
使用时机: 带约束的优化
示例: “在预算内选择最佳广告”
复杂度: O(n * 容量) 时间和空间

10. 无界背包问题

模式: 可无限次使用项目
使用时机: 硬币找零, 组合
示例: “达到余额的最小交易次数”
复杂度: O(n * 目标) 时间和空间

11. 斐波那契数

模式: 当前状态依赖先前状态
使用时机: 爬楼梯, 平铺问题
示例: “导航应用屏幕的方式”
复杂度: O(n) 时间, O(1) 空间优化

12. 最长公共子序列

模式: 比较两个序列
使用时机: 差异工具, 编辑距离
示例: “找到相似代码片段”
复杂度: O(m * n) 时间和空间

其他基本模式

13. 修改的二分搜索

模式: 在排序或旋转数组上进行二分搜索
使用时机: 在 O(log n) 内搜索
示例: “找到引入错误的版本”
复杂度: O(log n) 时间, O(1) 空间

14. 前K个元素

模式: 使用堆跟踪K个最大/最小
使用时机: 找到顶部项目
示例: “获取前K个热门标签”
复杂度: O(n log k) 时间, O(k) 空间

15. K路合并

模式: 合并K个排序数组/列表
使用时机: 组合排序数据
示例: “合并K个用户的活动动态”
复杂度: O(n log k) 时间, O(k) 空间

16. 回溯

模式: 用剪枝尝试所有可能性
使用时机: 生成排列, 组合
示例: “生成所有有效括号组合”
复杂度: 变化, 通常指数级

17. 并查集

模式: 跟踪连通组件
使用时机: 网络连通性, 分组
示例: “找到连接的朋友群组”
复杂度: O(α(n)) 摊销每次操作

18. 区间

模式: 合并、插入或找到重叠区间
使用时机: 日历调度, 时间范围
示例: “找到空闲会议时间段”
复杂度: O(n log n) 时间, O(n) 空间

19. 单调栈

模式: 维护递增/递减栈
使用时机: 下一个更大/更小元素
示例: “股票价格跨度计算”
复杂度: O(n) 时间, O(n) 空间

20. 字典树

模式: 用于字符串操作的前缀树
使用时机: 自动补全, 前缀匹配
示例: “实现搜索自动补全”
复杂度: O(m) 时间每次操作 (m = 词长度)

真实产品挑战示例

简单级别

Instagram: 喜欢计数器

真实场景: 计算用户帖子今天被喜欢的次数
模式: 哈希映射
数据结构: 字典/哈希映射
语言: Python, TypeScript, Kotlin, Swift

Slack: 未读消息

真实场景: 在频道中找到第一条未读消息
模式: 带标志的线性搜索
数据结构: 数组
教学: 早期终止

Uber: 计算费用

真实场景: 基于距离和时间计算行程成本
模式: 简单计算
数据结构: 数字
教学: 数学操作, 四舍五入

中等级别

Netflix: 前N个推荐

真实场景: 按评分找到前N部电影
模式: 前K个元素 (堆)
数据结构: 优先队列
教学: 堆操作, 部分排序

Amazon: 库存管理

真实场景: 找到库存低的商品
模式: 带阈值的过滤
数据结构: 数组 + 哈希映射
教学: 多标准过滤

Twitter: 热门标签

真实场景: 在时间窗口中找到最常用标签
模式: 滑动窗口 + 频率计数
数据结构: 队列 + 哈希映射
教学: 基于时间的窗口管理

LinkedIn: 连接度

真实场景: 找到两个用户之间的连接路径
模式: 广度优先搜索
数据结构: 图 (邻接表)
教学: 最短路径, 层跟踪

困难级别

Google日历: 找到会议时间段

真实场景: 为所有参与者找到空闲时间段
模式: 区间合并
数据结构: 区间数组
教学: 排序, 合并重叠区间

Spotify: 播放列表随机播放

真实场景: 真随机播放避免艺术家重复
模式: 修改的Fisher-Yates
数据结构: 数组
教学: 带约束的随机化

GitHub: 合并冲突解决

真实场景: 在文件中找到最长公共子序列
模式: 动态规划 (LCS)
数据结构: 2D数组
教学: DP状态定义, 优化

Airbnb: 搜索排名

真实场景: 按多个加权标准对列表排序
模式: 自定义排序 + 堆
数据结构: 带比较器的优先队列
教学: 复杂比较, 平局打破

交互式游乐场示例

Python游乐场

<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>🚀 LeetCode教师 - 两数之和 (Instagram喜欢)</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>🎯 两数之和</h1>
      <span class="difficulty easy">简单</span>
      <span class="pattern-badge">模式: 哈希映射</span>
      <span class="pattern-badge">数组</span>

      <div class="problem">
        <h3>📱 真实产品场景: Instagram喜欢</h3>
        <p>您正在构建Instagram的“互相喜欢”功能。给定一个喜欢您帖子的用户ID数组和一个目标总和,找到两个用户ID加起来等于目标的用户。</p>

        <h4 style="margin-top: 20px;">问题:</h4>
        <p>给定一个整数数组 <code>nums</code> 和一个整数 <code>target</code>,返回两个数字的索引,这些数字加起来等于 <code>target</code>。</p>

        <h4 style="margin-top: 20px;">示例:</h4>
        <code style="display: block; padding: 10px; background: rgba(0,0,0,0.3); border-radius: 5px;">
输入: nums = [2, 7, 11, 15], target = 9<br>
输出: [0, 1]<br>
解释: nums[0] + nums[1] = 2 + 7 = 9
        </code>

        <h4 style="margin-top: 20px;">约束:</h4>
        <ul style="margin-left: 20px;">
          <li>2 ≤ nums.length ≤ 10⁴</li>
          <li>仅存在一个有效答案</li>
          <li>不能使用同一元素两次</li>
        </ul>
      </div>

      <div class="stats">
        <div class="stat">
          <div class="stat-value" id="testsRun">0</div>
          <div>测试运行</div>
        </div>
        <div class="stat">
          <div class="stat-value" id="testsPassed">0</div>
          <div>通过</div>
        </div>
        <div class="stat">
          <div class="stat-value" id="attempts">0</div>
          <div>尝试次数</div>
        </div>
      </div>

      <div id="hints" style="margin-top: 20px;"></div>
    </div>

    <!-- 右面板: 代码编辑器 -->
    <div class="panel">
      <h2>💻 您的解决方案 (Python)</h2>
      <textarea class="code-editor" id="codeEditor">def two_sum(nums, target):
    """
    找到两个数字加起来等于目标。

    参数:
        nums: 整数列表
        target: 目标总和

    返回:
        两个索引的列表

    时间: O(n²) - 暴力法
    空间: O(1)

    TODO: 优化到 O(n) 使用哈希映射!
    """
    # 您的代码在这里
    pass


# 测试您的解决方案
if __name__ == "__main__":
    # 示例测试
    nums = [2, 7, 11, 15]
    target = 9
    result = two_sum(nums, target)
    print(f"结果: {result}")
</textarea>

      <div class="controls">
        <button class="btn btn-run" onclick="runCode()">▶️ 运行测试</button>
        <button class="btn btn-hint" onclick="getHint()">💡 获取提示</button>
        <button class="btn btn-solution" onclick="showSolution()">✨ 显示解决方案</button>
      </div>

      <div class="output" id="output">点击“运行测试”来测试您的解决方案...</div>
    </div>
  </div>

  <script>
    let currentHint = 0;
    let attempts = 0;
    let testsRun = 0;
    let testsPassed = 0;

    const hints = [
      "💡 提示 1: 暴力解决方案使用两个嵌套循环。您能做得更好吗?",
      "💡 提示 2: 考虑使用哈希映射来存储您已经看到的数字。",
      "💡 提示 3: 对于每个数字,检查 (目标 - 当前数字) 是否存在于您的哈希映射中。",
      "💡 提示 4: 在迭代时将数字的索引存储在哈希映射中。"
    ];

    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 {
        // 简单的Python模拟(在实际实现中,使用Pyodide或后端)
        output.innerHTML = '<div style="color: #4CAF50;">运行测试中...</div>

';

        testCases.forEach((test, i) => {
          const testDiv = document.createElement('div');
          testDiv.className = 'test-case';

          // 模拟测试执行
          testsRun++;
          const passed = Math.random() > 0.3; // 模拟结果

          if (passed) {
            testsPassed++;
            testDiv.innerHTML = `
              <strong style="color: #4CAF50;">✓ 测试 ${i + 1} 通过</strong><br>
              输入: nums = [${test.nums}], target = ${test.target}<br>
              预期: [${test.expected}]<br>
              得到: [${test.expected}]
            `;
          } else {
            testDiv.className += ' test-failed';
            testDiv.innerHTML = `
              <strong style="color: #F44336;">✗ 测试 ${i + 1} 失败</strong><br>
              输入: nums = [${test.nums}], target = ${test.target}<br>
              预期: [${test.expected}]<br>
              得到: undefined
            `;
          }

          output.appendChild(testDiv);
        });

        document.getElementById('testsRun').textContent = testsRun;
        document.getElementById('testsPassed').textContent = testsPassed;

        if (testsPassed === testCases.length) {
          output.innerHTML += '
<div style="color: #4CAF50; font-size: 1.2em; margin-top: 20px;">🎉 所有测试通过!做得好!</div>';
        }

      } catch (e) {
        output.innerHTML = `<div style="color: #F44336;">❌ 错误: ${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('无更多提示可用!尝试解决方案按钮。');
      }
    }

    function showSolution() {
      const solution = `def two_sum(nums, target):
    """
    使用哈希映射的优化解决方案。

    时间: O(n) - 单次遍历
    空间: O(n) - 哈希映射存储
    """
    seen = {}  # 数字 -> 索引

    for i, num in enumerate(nums):
        complement = target - num

        if complement in seen:
            return [seen[complement], i]

        seen[num] = i

    return []  # 未找到解决方案


# 测试您的解决方案
if __name__ == "__main__":
    nums = [2, 7, 11, 15]
    target = 9
    result = two_sum(nums, target)
    print(f"结果: {result}")  # [0, 1]`;

      document.getElementById('codeEditor').value = solution;
      alert('✨ 解决方案已揭示!研究模式并下次尝试自己实现它。');
    }
  </script>
</body>
</html>

功能:

  • 交互式代码编辑器
  • 实时测试执行
  • 渐进式提示
  • 视觉测试结果
  • 模式徽章
  • 进度跟踪

语言支持

Python

# 哈希映射模式
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

// 哈希映射模式
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

// 哈希映射模式
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

// 哈希映射模式
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: 核心算法 (中等)

  • 广度优先搜索和深度优先搜索
  • 二分搜索变体
  • 基本动态规划
  • 目标: 掌握常见模式

级别4: 高级技巧 (中等-困难)

  • 高级动态规划
  • 图算法
  • 回溯
  • 字典树 目标: 处理复杂场景

级别5: 面试准备 (困难)

  • 系统设计集成
  • 优化问题
  • 复杂动态规划
  • 高级图 目标: 通过任何面试

教学技巧

1. 模式识别

看问题 → 识别模式 → 应用模板 → 优化

2. 时间/空间分析

始终分析:
- 时间复杂度: O(?)
- 空间复杂度: O(?)
- 我们能做得更好吗?

3. 测试驱动开发

1. 阅读问题
2. 编写测试用例
3. 考虑边界情况
4. 编写解决方案
5. 运行测试
6. 优化

4. 优化旅程

暴力法 → 识别瓶颈 → 应用模式 → 优化空间

5. 面试沟通

- 陈述假设
- 询问澄清问题
- 大声思考
- 解释权衡
- 讨论替代方案

参考材料

全部包含在 /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俱乐部: 解决100个问题
  • 💎 优化: 从 O(n²) 改进到 O(n)
  • 🧠 无提示: 无任何提示解决

进度跟踪

  • 按难度解决的问题
  • 掌握的模式
  • 练习的语言
  • 成功率
  • 每个问题的平均时间
  • 连胜计数器

总结

此技能通过以下方式转变技术面试准备:

  • 真实产品上下文 - 通过实用场景学习
  • 模式识别 - 掌握20个基本模式
  • 多语言 - 用Python, TypeScript, Kotlin, Swift练习
  • 交互式 - 在浏览器中编码带即时反馈
  • 渐进式 - 从基础到专家构建
  • 有趣 - 游戏化带成就和进度跟踪
  • 实用 - 在真实面试中有效的技巧

“掌握模式, 通过面试。” 🚀


使用: 请求特定模式练习、难度级别或真实产品场景,并获取即时交互式编码游乐场!