前言
对于一个科班的学生来说,数据结构与算法是必修的一门课,我记得我们的数据结构与算法这门课是在大一下(应该没记错,要不然就是大二上)就开了,初学的时候数据结构还好,算法那真的是上的人难受,而且那个时候懒死了,算法课后都没有自己总结也没自己敲,就听了个课,所以这一片对于我来说还是很空白的。大二的时候报了蓝桥杯,当时一堆人说蓝桥杯很好混,随随便便三等奖,于是单枪匹马上了考场(其实自己当时的想法也是去试试水),果不其然,除了常规暴力完全没用上任何算法,而且蓝桥杯也不是以往的暴力杯了,所以什么奖都没得一个(还好报名费学校报销了,要不然亏麻了)。上大三后,我又报名了第十五届蓝桥杯,这一次就得好好准备准备了,当然能不能拿奖不重要了,能拿最好,不能拿也自己学了点算法,横竖不亏。算法是跟着y总的蓝桥杯辅导班学的,至于为什么要写到CSDN上呢?我是这样想的,学东西都得总结一遍吧,要不然总感觉不是自己的东西没吃到肚子里,而且自己总结的东西,自己回顾的时候也容易理解,写到CSDN上,既方便自己随时随地看,也能记录一下自己的学习路径,还能把自己的理解说出来,理解的好的话别人可以借鉴,理解有问题不深刻别人也可以指正,共同学习。每个算法的例题都是我都是选最简单的题,相当于模板题吧,主要是容易去理解这个算法是什么,怎么用,如果要学会活用,还得去多刷题,以下内容,都是个人的理解和总结,有错误的地方还请谅解指正,包括今后自己也会根据自己学习水平去修改内容。
递归
理解与总结
递归常用于深度优先搜索,以树为例,如果一个问题可以用树的形式表示出来,那么就可以用深度优先搜索去遍历这棵树得出答案。然后就是递归适用于枚举各种类型或者算有多少种方案,每个问题都可以划分成N个小问题解决的题,做递推最好能从很小的例子去画一棵树,然后观察写代码。写的过程一定要设立递归终止条件,不然容易一直死递归,一般我都会在写递归方法时第一句代码就是特判然后终止递归。
例题
题目
92. 递归实现指数型枚举
思路
这道题我第一想法其实是用枚举法的,但是是可以用递归那就用递归写。用递归那必然可以画出树,画出树,就可以深度优先遍历写出所有答案。很显然用题目给的例子可以画出二叉树(如图),因为每一次仅仅是去判断当前位置的数选还是不选两种选择。
代码
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Scanner;
public class Main {
static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
static int n = new Scanner(System.in).nextInt() + 1; // 因为数从1开始的,后面索引即代表该数
static int[] sta = new int[n]; // sta数组用于记录该位数上的状态。1选,0不选
public static void main(String[] args) throws IOException {
/*从1开始保证了升序*/
recursion(1);
out.flush();
}
/*递归输出从1到n的正整数中的全部组合,p用于记录当前的位置*/
static void recursion(int p) throws IOException {
if (p == n) {
for (int i = 1; i < n; i++) {
if (sta[i] == 1) {
out.write(i + " ");
}
}
out.write("\n");
} else {
/*该位数选*/
sta[p] = 1;
recursion(p + 1);
/*该位数不选*/
sta[p] = 0;
recursion(p + 1);
}
}
}