查看: 977| 回复: 0
跳转到指定楼层
上一主题 下一主题
收起左侧

[找工就业] 一套通用框架,解决任何 LeetCode 题目

全局:

2026(7-9月)-CS博士+5-10年 | 猎头| 管理岗位全职@

注册一亩三分地论坛,查看更多干货!

您需要 登录 才可以下载或查看附件。没有帐号?注册账号

x
求加米
核心信念:LeetCode 考的不是"你背了多少题",而是"你能不能把一道没见过的题,映射到你见过的模式上"。 刷 1000 道题却不总结,不如吃透 15 个模式 + 一套固定流程。这篇讲的就是那套流程。

为什么需要框架
大多数人刷题的失败模式是这样的:读完题 → 盯着屏幕 → 凭直觉写 → 卡住 → 看答案 → "哦原来是这样" → 换一道题又不会。
问题不在于智商,而在于没有可复用的流程。真正稳定的解题者,脑子里跑的是一套几乎机械化的步骤:先分类,再套模板,最后验证。这篇文章把这套流程拆成三层:. 1point 3 acres
  • 五步解题流程——从读题到 AC 的固定动作序列;
  • 两张速查表——从"约束条件"反推复杂度,从"题目信号"反推模式;
  • 核心模式模板——十几个模式的 Python 骨架,背下来就能套。


第一层:五步解题流程
把每道题都当成同一个流水线来处理。面试时尤其重要——面试官看的不是你多快写完,而是你思考是否有章法。. 1point3acres
第 1 步 · 读题与澄清(Understand)
不要急着写。先做四件事:
  • 复述题目:用自己的话把题目讲一遍,确认理解没跑偏(面试中直接说出来)。
  • 明确输入输出:数据类型是什么?有没有空输入、负数、重复元素?返回值是索引还是值?
  • 看约束条件:
    1. n
    复制代码
    有多大?数值范围?这一步直接决定了你的目标复杂度(见第二层速查表)。
  • 手举一个例子:拿一个小例子走一遍,确认自己真的懂题意。再想一个边界例子(空、单元素、全相同)。
面试信号:主动问 clarifying question("数组可以为空吗?""有重复吗?")本身就是加分项。
第 2 步 · 定位模式(Match)
这是最关键的一步,决定了后面所有动作。问自己:
"这道题的信号,指向哪个已知模式?"
用第二层的"信号 → 模式"速查表去匹配。90% 的题目会落在十几个模式里。如果一眼看不出来,先想暴力解——暴力解往往会暴露出结构("我在重复计算子问题" → DP;"我在枚举所有组合" → 回溯)。
第 3 步 · 设计思路(Plan)
  • 先说暴力解:明确它的复杂度。哪怕最终不用,它也是你的 baseline,面试中先给暴力解永远是安全的。
  • 再优化:暴力解的瓶颈在哪?能不能用哈希表把 O(n) 查找降到 O(1)?能不能用双指针省掉一层循环?能不能缓存子问题(DP)?
  • 用例子验证思路:在写代码前,拿第 1 步的例子在纸上/口头把算法走一遍。如果思路在例子上都跑不通,代码一定错。
第 4 步 · 编码(Implement).
  • 套对应模式的模板(第三层),别从零发明。
  • 变量命名清晰,先写主干再补细节。
  • 一边写一边讲你在干什么(面试中不要沉默写代码)。
第 5 步 · 验证与复杂度(Review)
  • 手动 dry run:拿正常例子 + 边界例子逐行走一遍,别信"感觉对"。
  • 边界检查清单:空输入、单元素、全相同、最大规模、负数/溢出。
  • 报出复杂度:时间和空间,一定要主动说,并解释为什么。


第二层:两张速查表
速查表 A:从约束条件反推复杂度
这是被严重低估的技巧。约束里的
  1. n
复制代码
直接告诉你目标复杂度,从而反推该用什么模式。看到
  1. n
复制代码
就应该立刻在心里定位:. 1point3acres.com
  1. n
复制代码
的规模
可接受的复杂度
典型模式
  1. n ≤ 10 ~ 12
复制代码
  1. O(n!)
复制代码
、
  1. O(2ⁿ·n)
复制代码
全排列回溯
  1. n ≤ 20
复制代码
  1. O(2ⁿ)
复制代码
子集枚举、状压 DP(bitmask)
  1. n ≤ 100
复制代码
  1. O(n³)
复制代码
区间 DP、Floyd 最短路
  1. n ≤ 1,000
复制代码
  1. O(n²)
复制代码
二维 DP、暴力双循环
  1. n ≤ 10⁵
复制代码
  1. O(n log n)
复制代码
排序、二分、堆、滑动窗口
  1. n ≤ 10⁶ ~ 10⁷
复制代码
  1. O(n)
复制代码
一次扫描、双指针、哈希、前缀和
  1. n ≥ 10⁹
复制代码
  1. O(log n)
复制代码
或
  1. O(1)
复制代码
二分答案、数学公式
实战用法:看到
  1. n ≤ 20
复制代码
,几乎可以断定是状压/回溯;看到
  1. n = 10⁵
复制代码
却想写
  1. O(n²)
复制代码
,立刻知道会 TLE,必须优化到
  1. O(n log n)
复制代码
。
速查表 B:从题目信号反推模式
题目信号
模式. 1point 3acres
典型复杂度
有序数组里找目标 / 找一对数
二分查找 / 双指针
  1. O(log n)
复制代码
/
  1. O(n)
复制代码
连续
子数组 / 子串的最优值或计数
滑动窗口
  1. O(n)
复制代码
"所有"组合 / 排列 / 子集.
回溯
  1. O(2ⁿ)
复制代码
/
  1. O(n!)
复制代码
"有多少种方式" / 最优代价,且有重叠子问题
动态规划
视题而定
树 / 图的遍历、连通性
DFS / BFS
  1. O(V+E)
复制代码
无权图
最短路径
/ 最少步数
BFS
  1. O(V+E)
复制代码
Top K / 第 K 大 / 数据流中位数. 1point 3acres
堆(heap)
  1. O(n log k)
复制代码
下一个更大 / 更小元素、柱状图接雨水
单调栈
  1. O(n)
复制代码
区间合并 / 重叠判断-baidu 1point3acres
排序 + 扫描
  1. O(n log n)
复制代码
链表找环 / 找中点
快慢指针
  1. O(n)
复制代码
动态合并集合 / 判断连通
并查集(Union-Find)
  1. ~O(α(n))
复制代码
子数组和 / 区间和
前缀和 + 哈希
  1. O(n)
复制代码
网格里的岛屿 / 连通区域
. ----
Flood Fill(DFS/BFS)
  1. O(m·n)
复制代码
大量字符串前缀查询
字典树(Trie) ..
  1. O(L)
复制代码
需要 O(1) 判断是否存在 / 计数
哈希表 / 集合
  1. O(1)
复制代码
求 k 个有序结构的合并
堆 / 分治.
  1. O(n log k)
复制代码

. .и
第三层:核心模式模板(Python)
背下这些骨架,遇到对应模式直接套。以下都是可以当"肌肉记忆"的写法。
1. 双指针(有序数组找一对)
def two_sum_sorted(nums, target):
    lo, hi = 0, len(nums) - 1
    while lo < hi:
        s = nums[lo] + nums[hi]
        if s == target:
.             return [lo, hi]
        elif s < target:. 1point3acres
            lo += 1        # 和太小,左指针右移
        else:
            hi -= 1        # 和太大,右指针左移
    return []
2. 快慢指针(链表找环)
def has_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:. From 1point 3acres bbs
            return True
    return False
3. 滑动窗口(变长窗口). 1point3acres.com
from collections import defaultdict

def longest_valid_window(s):
    window = defaultdict(int)
    left = 0.
    res = 0
    for right, c in enumerate(s):
        window[c] += 1
        # 窗口不合法时,从左边收缩
.1point3acres        while not is_valid(window):
            window[s[left]] -= 1
            left += 1
        res = max(res, right - left + 1)
    return res
4. 二分查找(含"二分答案"心法)
def binary_search(nums, target): ..
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = (lo + hi) // 2. 1point3acres.com
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1
进阶:当题目问"最小的可行值 / 最大的满足条件的 x",且答案单调时,用二分答案——不是在数组上二分,而是在答案的取值范围上二分,配一个
  1. check(x)
复制代码
判定函数。看到
  1. n ≥ 10⁹
复制代码
经常就是它。
5. BFS(无权图最短步数 / 层序)
from collections import deque

def bfs(start, target):
    q = deque([start])-baidu 1point3acres
    visited = {start}
    steps = 0
    while q:
        for _ in range(len(q)):          # 一次处理一整层
            node = q.popleft()
            if node == target:
                return steps
            for nxt in neighbors(node):
                if nxt not in visited:
                    visited.add(nxt)
                    q.append(nxt)
        steps += 1.google  и
    return -1
6. DFS / 回溯(所有组合 / 排列 / 子集)
def backtrack(path, choices, res):
    if is_complete(path):
        res.append(path[:])             # 存副本,不是引用
        return
    for i, choice in enumerate(choices):. 1point 3 acres
        path.append(choice)             # 做选择
        backtrack(path, next_choices(choices, i), res)
        path.pop()                      # 撤销选择
回溯三要素:路径(已选)、选择列表(可选)、结束条件。
7. 动态规划(五步定式)
DP 不要背题,要背推导流程:
  • 定义状态:
    1. dp[i]
    复制代码
    或
    1. dp[i][j]
    复制代码
    代表什么?
  • 状态转移方程:
    1. dp[i]
    复制代码
    由哪些更小的状态推出?
  • 初始化:base case 是什么?
  • 遍历顺序:从小到大 / 从后往前 / 二维的行列顺序。
  • 返回值:答案是
    1. dp[n]
    复制代码
    还是
    1. max(dp)
    复制代码
    ?
# 例:爬楼梯 / 打家劫舍类
def rob(nums):
    prev, cur = 0, 0
    for x in nums:. .и
        prev, cur = cur, max(cur, prev + x)   # 状态转移
    return cur
8. 单调栈(下一个更大元素)
def next_greater(nums):. From 1point 3acres bbs
    res = [-1] * len(nums)
    stack = []                          # 存下标,栈内单调递减
    for i, x in enumerate(nums):
        while stack and nums[stack[-1]] < x:
            res[stack.pop()] = x
        stack.append(i)
    return res
9. 堆 / Top K(维护大小为 k 的堆). 1point 3 acres
import heapq. 1point3acres.com

def top_k(nums, k):. .и
    heap = []                           # 最小堆
    for x in nums:. 1point3acres.com
        heapq.heappush(heap, x). .и
        if len(heap) > k:
            heapq.heappop(heap)         # 弹掉最小的,堆里始终是最大的 k 个. From 1point 3acres bbs
    return heap
10. 并查集(动态连通性)
class UnionFind:
    def __init__(self, n):. 1point3acres.com
        self.parent = list(range(n))
        self.rank = [0] * n

    def find(self, x):
        while self.parent[x] != x:
            self.parent[x] = self.parent[self.parent[x]]   # 路径压缩. .и
            x = self.parent[x]
        return x

    def union(self, a, b):
        ra, rb = self.find(a), self.find(b)
        if ra == rb:
            return False
        if self.rank[ra] < self.rank[rb]:
            ra, rb = rb, ra
. Waral dи,        self.parent[rb] = ra
        if self.rank[ra] == self.rank[rb]:
            self.rank[ra] += 1. 1point3acres.com
        return True. 1point3acres
. check 1point3acres for more.
完整示范:用框架解一道题
题目:给定字符串
  1. s
复制代码
,求不含重复字符的最长子串的长度。(LC 3)
第 1 步 · 读题:输入字符串,输出一个整数(长度)。边界:空串返回 0,全相同字符返回 1。约束
  1. n ≤ 5×10⁴
复制代码
→ 目标
  1. O(n)
复制代码
。
第 2 步 · 定模式:关键词是"连续子串 + 最长" → 速查表 B 直接命中滑动窗口。
第 3 步 · 思路:暴力解是枚举所有子串再判重,
  1. O(n²)
复制代码
甚至
  1. O(n³)
复制代码
,在
  1. n=5×10⁴
复制代码
下会超时。滑动窗口:右指针扩张,遇到重复字符时收缩左指针,用一个集合/哈希记录窗口内字符。. Χ
第 4 步 · 编码:.1point3acres
def length_of_longest_substring(s):
    seen = set()
    left = 0. From 1point 3acres bbs
    res = 0
    for right, c in enumerate(s):. 1point 3 acres
        while c in seen:                # 出现重复,收缩左边界
            seen.remove(s[left])
            left += 1. Waral dи,
        seen.add(c)
        res = max(res, right - left + 1)
    return res
第 5 步 · 验证:
  1. "abcabcbb"
复制代码
→ 3(
  1. abc
复制代码
);
  1. ""
复制代码
→ 0;
  1. "bbbb"
复制代码
→ 1。复杂度:每个字符最多进出窗口一次,时间
  1. O(n)
复制代码
,空间
  1. O(min(n, 字符集大小))
复制代码
。✅ 符合目标。
整套流程走下来,没有一步是"灵光一现",全是可复现的动作。

卡住了怎么办:解题急救清单. Χ
写题时卡住是常态。按顺序试这几招:
  • 回到暴力解——先能跑通,再谈优化。有暴力解总比交白卷强。
  • 换个数据结构——"我在反复查找?" → 哈希表;"我要频繁取最值?" → 堆;"我在维护有序?" → 有序结构 / 二分。
  • 正难则反——正着推不动,试试从结果倒推、从后往前遍历、或求补集。
  • 画图 / 举更大的例子——很多规律要在
    1. n=5
    复制代码
    的例子上才看得出来。
  • 找不变量——双指针、单调栈的本质都是"维护某个不变量"。问自己"循环里什么东西始终成立?"
  • 拆成子问题——能不能分治?能不能先排序把问题简化?


如何练习:让框架变成本能
  • 按模式刷,别随机刷:一次集中攻一个模式(比如连做 10 道滑动窗口),比东一榔头西一棒子有效得多——你要的是"看到信号就条件反射"。
  • 刷完必总结:每道题记一句话——"这题的信号是 X,所以用模式 Y"。这句话比完整题解更值钱。
  • 间隔重复:把"信号 → 模式"的映射和模板做成卡片,用间隔重复复习。模式模板就该像九九乘法表一样是肌肉记忆。
  • 限时 + 讲出来:模拟面试环境,边写边讲。能把思路讲清楚,比自己闷头写对更重要。
  • 回顾错题:错过的题两周后重做。如果还是卡在同一步,说明那个模式没真正吃透。


一句话总结
读题定复杂度 → 信号定模式 → 暴力打底 → 套模板 → dry run 验证。 把每道题都塞进这条流水线,"没见过的题"会越来越少,因为你处理的从来不是"题",而是"模式"。

评分

参与人数 3大米 +12 收起 理由
gongchangzhANYK + 1 很有用的信息!
instant_dev + 10 给你点个赞!
匿名用户-WL38F + 1 谢谢分享!

查看全部评分


上一篇:Mathwork OA
下一篇:请问一下目前市场我适合找什么样的工作
您需要登录后才可以回帖 登录 | 注册账号
隐私提醒:
  • ☑ 禁止发布广告,拉群,贴个人联系方式:找人请去🔗同学同事飞友,拉群请去🔗拉群结伴,广告请去🔗跳蚤市场,和 🔗租房广告|找室友
  • ☑ 论坛内容在发帖 30 分钟内可以编辑,过后则不能删帖。为防止被骚扰甚至人肉,不要公开留微信等联系方式,如有需求请以论坛私信方式发送。
  • ☑ 干货版块可免费使用 🔗超级匿名:面经(美国面经、中国面经、数科面经、PM面经),抖包袱(美国、中国)和录取汇报、定位选校版
  • ☑ 查阅全站 🔗各种匿名方法

本版积分规则

>
快速回复 返回顶部 返回列表