时间:2025-04-13 20:43
人气:
作者:admin
能问出这个问题?你已经走在提升算法水平的核心路上了。
刷题本身只是手段,真正关键的就是「算法思维过程」。
下面总结给你一套可执行的“算法思维训练体系”,直接拿去用:
✅ 错题是宝藏,做不出来没关系,核心是:
???? 建议: 每次遇到新题,至少逼自己想10分钟,用以下问题问自己:
1. 有没有最直接的暴力解?(不要怕,先写出来)
2. 会不会超时?大概什么复杂度?
3. 有没有能拆分成两个部分的结构?(分治、分组)
4. 有没有能用哈希表、双指针、前缀和、排序优化的地方?
5. 这题和我做过的哪道题像?能借鉴吗?
比如:
| 学到的算法 | 刻意练习方向 |
|---|---|
| 哈希表 | 练「两数之和」、「四数之和」、「异或」、「字符统计」 |
| 双指针 | 练「有序数组去重」、「盛水最多的容器」、「三数之和」 |
| 前缀和、差分 | 练「区间和」、「二维前缀和」、「差分数组」 |
| 滑动窗口 | 练「最小子串覆盖」、「最长无重复子串」、「滑动最大值」 |
| 递归 & 回溯 | 练「全排列」、「组合」、「子集」、「N皇后」 |
| 二分 | 练「搜索区间」、「求平方根」、「最大最小问题」 |
???? 核心在于:每种方法,找到 3-5 道有代表性的题目,死磕,做到:
很多题目是文字游戏,关键在于“把问题抽象成熟悉的模型”:
| 题目场景 | 建模思路 |
|---|---|
| 找满足条件的组合 | 转换成「nSum」模型 |
| 连续区间内最大/最小值 | 想到「前缀和」「单调队列」「滑动窗口」 |
| 涉及顺序的问题 | 想到「栈」「队列」「递归」 |
| 统计方案数 | 想「dp」有没有必要 |
| 树、图的遍历 | 立刻往「BFS」「DFS」靠 |
先刷经典题,锻炼你对这些思维的掌控力:
1. 数组:两数之和、三数之和、盛水容器
2. 哈希表:有效的字母异位词、四数相加
3. 双指针:有序数组去重、最小覆盖子串
4. 栈/队列:有效括号、每日温度
5. 动态规划:爬楼梯、背包、最长子序列
6. 二分:搜索区间、旋转数组
7. 前缀和 & 差分:区间和,子数组和为K
8. 图:BFS、DFS模板题
✅ 你做一道题,试图给“未来的自己”写一份思路笔记:
1. 题目的核心是啥?本质模型?
2. 我一开始想到的暴力解法是什么?为什么不行?
3. 最终解法用了啥优化技巧?
4. 这个技巧能迁移到哪里?
???? 比如:
| 类型 | 推荐 |
|---|---|
| 刷题平台 | 力扣(LeetCode)、AcWing(有中文讲解) |
| 题单 | LeetCode Top 100、经典算法分类题单 |
| 书 | 《剑指 Offer》、《程序员代码面试指南》 |
| 视频 | 哔哩哔哩 左神、花花酱算法、代码随想录 |
| 社区 | 公众号「代码随想录」、力扣官方讨论区 |
这就是学会「算法思维过程」的关键步骤。
借鉴题目 "4Sum II"(力扣:四数之和),很经典。接下来我带你走一遍“正常人做题的思路 + 试错 + 碰壁 + 优化”的完整过程。
???? 第一步:最直接的暴力思路
【想法】
题目问 (i, j, k, l) 满足 A[i] + B[j] + C[k] + D[l] == 0
count++【代码雏形】
int count = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
for (int k = 0; k < N; k++) {
for (int l = 0; l < N; l++) {
if (A[i] + B[j] + C[k] + D[l] == 0) count++;
}
}
}
}
【试错点】
O(N^4)???? 第二步:尝试优化——分组 + 预处理
【灵感来源】
A[i] + B[j] + C[k] + D[l] == 0 可以拆成两部分(A[i] + B[j]) + (C[k] + D[l]) == 0A[i] + B[j] 所有可能,然后去查找 -(C[k] + D[l]),问题会简单很多!【核心突破】
unordered_map<int, int>,key 是 A[i] + B[j] 的和,value 是出现的次数(因为可能有重复)C[k] + D[l],每算一个就看 -(C[k] + D[l]) 是否在 map 里???? 第三步:算算复杂度
A[i] + B[j] 枚举一遍:O(N^2)C[k] + D[l] 再枚举一遍:O(N^2)O(1)O(N^2) + O(N^2) = O(N^2),完美解决500的数据量!???? 第四步:模拟试错版本
假设:
A = [1, 2], B = [-2, -1], C = [-1, 2], D = [0, 2]
先处理 A + B:
结果:
sumAB = {
-1: 1,
0: 2,
1: 1
}
再处理 C + D 并查 map:
1 是否在 sumAB-1 是否在 sumAB-2 是否在 sumAB-4 是否在 sumAB查到的部分:
sumAB,有1个 → 计数 +1sumAB,有1个 → 计数 +1最终答案:2
✍ 第五步:总结一般解题套路(非常重要)
| 阶段 | 做法 | 典型思路 |
|---|---|---|
| 1. 暴力尝试 | 四层循环,发现复杂度炸了 | 暴力总是第一想法 |
| 2. 分组降维 | 发现可以 (A+B) (C+D) 分组 |
分组思想 |
| 3. 哈希优化 | 用 map 统计出现次数,反查匹配 | 空间换时间 |
| 4. 时间复杂度 | 优化到 O(N^2) | 可接受 |
| 5. 通用套路 | 多数求和问题可尝试「分组 + 哈希表」 | nSum问题 |
???? 这题的本质