👇 “一道题拿到手,我怎么判断用什么算法,比如贪心、回溯、动态规划、双指针、并查集……?”
下面是我总结的系统性判断策略,包括:
-
📌 常见算法类型的“题目特征判断表”
-
🔍 判断路线图:如何从题目关键词逐步缩小范围
-
✅ 实战技巧:如果还是不确定该怎么办
🧭 一、各算法的典型“题目特征”识别法
算法/思想 | 出现关键词 / 特征 | 常见题型/例子 |
---|---|---|
贪心 | “尽可能多/少”、“最小/最大”、“能否尽早完成”、“局部最优导致全局最优” | 会议安排、区间合并、跳跃游戏 |
动态规划 | “最优子结构”、“重叠子问题”、“求最大/最小/方案数/路径数/是否可达”等 | 背包问题、子序列、字符串匹配 |
回溯 / DFS | “所有可能解”、“组合/排列/子集”、“需要枚举所有情况”、“剪枝” | N 皇后、单词搜索、括号生成 |
双指针 | “有序数组/字符串”、“寻找子串/窗口/连续段”、“求某种条件下的区间” | 最小覆盖子串、盛最多水、滑动窗口 |
二分 | “查找特定数值/最小值/最大值”、“单调性”、“最小满足条件的x” | 木材切割、找最小天数、Kth元素 |
图算法 | “路径/最短路/连通性/拓扑排序/图中是否有环”等 | 最短路径、课程安排、岛屿数量 |
并查集 | “集合合并”、“是否属于同一集合”、“冗余连接” | 朋友圈、冗余连接、岛屿问题 |
前缀和/差分 | “区间快速求和”、“多次修改一个区间”、“频繁查询” | 和为K的子数组、树状数组 |
BFS/DFS | “从起点出发逐步扩展”、“最少步数”、“能否到达”、“所有可能路径” | 迷宫问题、最短路径、网格遍历 |
滑动窗口 | “最短/最长连续子数组”、“满足某种条件的窗口” | 最小覆盖子串、无重复最长子串 |
🔍 二、识别方法:题目到方法的判断流程图
题目 → 看是否有“最优子结构”
→ 有 → 考虑动态规划
→ 否 → 看是否是“所有解”“全排列”“组合” → 回溯或 DFS
→ 否 → 看是否是“最小步数”或“层层推进” → BFS
→ 否 → 看是否可以“提前做决策” → 贪心
→ 否 → 看是否是“有序数组/两个数组” → 双指针
→ 否 → 图论、并查集、模拟...
🎯 三、实战判断技巧与问自己几个关键问题:
🔑 自问自答法
问题 | 倾向的算法类型 |
---|---|
是否在求最优解? | 动态规划 / 贪心 |
是否要穷举所有可能性? | 回溯 / DFS |
是否只要找到一种解? | DFS / BFS |
是否要求子串/区间满足某种条件? | 滑动窗口 / 双指针 |
是否是图结构题?路径? | BFS / DFS / Dijkstra / 并查集 |
是否涉及很多区间/频繁修改? | 差分数组 / 树状数组 / 线段树 |
🎓 四、如果实在判断不出,怎么办?
-
从暴力法开始写:写个 DFS 枚举或者简单暴力,找出重复子问题,再尝试优化(动态规划)。
-
画图或模拟过程:很多题其实隐藏了图/状态转移模型。
-
查看变量的关系:是否单调?是否满足“可剪枝”?都能帮助你识别是贪心 or DP。
📘 举几个题目的判断示范:
题目 | 特征关键词 | 推荐算法 |
---|---|---|
322. 零钱兑换 | 最少硬币组成金额 → “最优解” + 重叠子问题 | 动态规划 |
55. 跳跃游戏 | 能否到终点 → 不需要所有解、可提前做决策 | 贪心 |
17. 电话号码字母组合 | 所有可能组合 → 枚举全部可能 | 回溯 |
239. 滑动窗口最大值 | 滑动窗口 + 最值 | 单调队列 |
200. 岛屿数量 | 网格遍历、连通区域 → 图结构 | DFS / BFS |
📌 最后建议
🚨 刷题初期不要强行判断用哪种算法,先写暴力,写熟不同题型后,识别能力自然会提高!