这篇是系列总纲,后面会逐篇展开讲分治法、动态规划、贪心、回溯、递归递推、链表树图六大块。如果你也在备考软件设计师,建议先收藏这篇,后面每出一篇我都会把链接补进来。
一、先说说为什么写这个系列
说实话,备考软件设计师的时候,下午题最让我发怵的就是第四题。
前三题------数据流图、数据库、UML------套路相对固定,练熟了基本就是送分题。第五六题二选一,Java或C++的设计模式填空,你前面如果跟我一起把设计模式系列啃完了,那两题基本就是白给。
但第四题,C语言算法,15分,必答,躲不掉。
我第一次做真题的时候,看到这题脑子里就两个字:放弃。什么动态规划、回溯法、分治法,代码里挖三四个空,让我填?我连题目描述都读不懂,填个锤子。
但后来我发现,这题其实没有想象中那么可怕。它考的不是让你从零写算法,而是在一段已经搭好框架的代码里,补全关键的几行 。而且这题有个特点:就算你不会完整算法,也能拿到基础分。
比如问你"该算法采用了什么策略",选项里就那几个:分治、动态规划、贪心、回溯。就算代码没看懂,根据题目描述和代码结构,蒙一个也有概率对。
再比如时间复杂度,快排就是 O(nlogn),暴力递归就是 O(2^n),这些属于"背了就有分"的东西。
所以我想,与其让第四题成为大家的噩梦,不如把它拆开了、揉碎了,一篇一篇讲清楚。这个系列的目标不是让你成为算法大神,而是让你在考场上能看懂题、能填上空、能拿到7~10分------对于45分及格线来说,这够了。
二、第四题到底长什么样?
在动手之前,先搞清楚敌情。
下午第四题,固定 15 分,必答题,形式基本是这样的:
题干:给你一段场景描述,比如"用分治法求最大子数组和"、"用回溯法解决0-1背包问题"、"用动态规划求最长公共子序列"等等。
代码:给出一段不完整的 C 语言代码,里面挖了 3~4 个空。
问题:
-
代码填空(一般 6~9 分):补全关键代码行。
-
算法策略识别(一般 3 分):问采用了什么算法设计策略。
-
复杂度分析(一般 3 分):问时间复杂度、空间复杂度。
-
实例推演(一般 3 分):给定一组输入,让你写出输出结果。
你看,策略识别和复杂度分析这两块,其实是可以通过"理解+记忆"拿分的,不一定需要你把代码完全吃透。而代码填空和实例推演,则需要你真正理解算法逻辑。
这个系列的重点,就是帮你在"理解"和"记忆"之间找到一个平衡点:用最少的时间,拿到最稳的分数。
三、算法地图:六大板块总览
我把第四题常考的内容,归纳成了六大板块。后面每一篇博客,就对应一块。
| 板块 | 核心内容 | 在软考中的常见考法 |
|---|---|---|
| 分治法 | 归并排序、快速排序、二分查找、最大子数组、最近点对 | 递归框架填空、递归终止条件、合并步骤 |
| 动态规划 | 0-1背包、最长公共子序列、最长递增子序列、矩阵链乘 | 状态转移方程填空、填表过程、最优值推导 |
| 贪心算法 | 活动选择、哈夫曼编码、最小生成树(Prim/Kruskal)、单源最短路径(Dijkstra) | 贪心策略选择、证明贪心正确性、代码填空 |
| 回溯法 | 0-1背包、N皇后、子集和、图的m着色 | 解空间树、剪枝条件、递归回溯框架 |
| 递归与递推 | 斐波那契、阶乘、汉诺塔、全排列、组合 | 递归出口、递归调用、递推公式 |
| 链表/树/图 | 链表操作、二叉树遍历、BST、图的遍历(DFS/BFS)、最短路径、最小生成树 | 指针操作、遍历顺序、邻接矩阵/表 |
这六块基本覆盖了第四题 90% 以上的考点。当然,偶尔也会冒出一些冷门题,比如 KMP 算法、拓扑排序之类的,但那些属于"随缘"范畴,先把这六块吃透,基本盘就稳了。
四、备考策略:别想着拿满分,想着拿稳分
这里必须泼一盆冷水:第四题对于非计算机科班或者工作多年不碰算法的人来说,想拿满分很难。
但好消息是,软考是45分及格,不是75分满分。前面三题你拿稳了,第五六题设计模式拿稳了,第四题拿个7~10分,完全够用了。
我的建议是:
1. 先拿"送分题"
-
算法策略识别:分治、DP、贪心、回溯,四选一,看代码结构基本能猜出来。
-
复杂度分析:把常见算法的复杂度背下来,快排 O(nlogn)、冒泡 O(n²)、二分 O(logn) 等等。
-
这些分,不拿白不拿。
2. 代码填空抓"套路"
-
分治法就是"分解-递归-合并"三段式;
-
动态规划就是"初始化-填表-回溯"三段式;
-
回溯法就是"递归-约束检查-回溯"三段式。
-
每个套路都有固定的代码模板,记住了,填空就是填模板里的关键变量。
3. 实例推演勤动手
- 给定输入,自己在草稿纸上一步一步走一遍代码。不要嫌麻烦,走一遍比看十遍都管用。
4. 时间分配要合理
- 如果你算法基础确实薄弱,考场上第四题可以放在最后做。先把前面稳拿的分拿到手,再回来啃这块硬骨头。别在第四题上死磕,导致后面设计模式的送分题没时间做。
五、系列预告
下面是这个系列的更新计划,每写一篇我都会把链接补进来:
-
【分治法】 ------ 从归并排序到最大子数组,学会"拆、治、合"三段式
-
【动态规划】 ------ 0-1背包和最长公共子序列,理解"状态转移"到底在转移什么
-
【贪心算法】 ------ 活动选择和最小生成树,为什么"局部最优"能凑成"全局最优"
-
【回溯法】 ------ N皇后和0-1背包,画解空间树,找剪枝点
-
【递归与递推】 ------ 斐波那契、汉诺塔、全排列,递归出口怎么写
-
【链表/树/图】 ------ 指针操作、遍历顺序、邻接矩阵,数据结构的基础功
每一篇都会包含:
-
算法思想:用大白话讲清楚这玩意儿到底在干嘛
-
代码框架:给出软考风格的 C 语言代码模板
-
真题拆解:拿一道历年真题,手把手带你看题、填空、分析复杂度
-
常见陷阱:哪些地方容易丢分,哪些地方可以偷分
六、写在最后
算法这东西,说到底不是背出来的,是练出来的。但软考不是算法竞赛,它考的是你能不能在给定的框架里,把缺的那几块拼图补上。
所以别被第四题吓到。跟着这个系列,一篇一篇啃下来,你会发现:原来那些看起来高不可攀的算法,拆开了也就是几行代码的事儿。
及格线 45 分,不是让你做对所有题,而是让你别放弃任何一题。
第四题,我们一道一道来。
下一篇:【软考算法】软件设计师下午第四题之分治法:归并排序与最大子数组的"拆、治、合"