递归简介
递归算法的基本思想是:把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
一个问题要采用递归方法来解决时,必须符合以下三个条件:
-
解决问题时,可以把一个问题转化为一个新的问题,而这个新的问题的解决方法仍与原问题的解法相同,只是所处理的对象有所不同,这些被处理的对象之间是有规律的递增或递减;
-
可以通过转化过程是问题得到解决;
-
必定要有一个明确的结束递归的条件,否则递归将会无止境地进行下去,直到耗尽系统资源。也就是说必须要某个终止递归的条件。如求阶乘问题,我们要求n的阶乘(n!),可以把这个问题转化为n*(n-1)!,而要求(n-1)!又可转化为(n-1)*(n-2)!,……,这里面都有一个一个数乘以另一个数阶乘的问题,被处理的对象分别是n,n-1,……,是有规律的递减。但是我们不能让程序无休止的乘下去,必须要给他一个结束条件,该问题恰好有一个结束条件,那就是当n=0时,0!=1。
迷宫回溯问题
原题:
https://www.nowcoder.com/questionTerminal/cf24906056f4488c9ddb132f317e03bc
代码实现
//i表示当前坐标的横坐标,j表示纵坐标,input代表迷宫,res路径信息
public static boolean mazeTrack(int[][] input, int i, int j, int rowNum, int colNum, Stack<String> res) {
//如果到达终点返回true
if (input[rowNum - 1][colNum - 1] == 2) return true;
//如果是墙或者路已经走了,返回false
if (i < 0 || i >= rowNum || j < 0 || j >= colNum || input[i][j] != 0) {
return false;
}
//说明路暂时可以走,标为2
input[i][j] = 2;
//递归判断上下左右是否有路,如果都为false,这个地方封路
if (!mazeTrack(input, i, j + 1, rowNum, colNum, res) && !mazeTrack(input, i + 1, j, rowNum, colNum, res) && !mazeTrack(input, i - 1, j, rowNum, colNum, res) && !mazeTrack(input, i, j - 1, rowNum, colNum, res)) {
input[i][j] = 1;
return false;
}
res.push("(" + i + "," + j + ")");
return true;
}
八皇后问题
原题:
https://www.nowcoder.com/practice/de1e1ff46cd641178a147166156c9d83?tpId=3&tqId=10896&rp=0&ru=/ta/hackathon&qru=/ta/hackathon/question-ranking
代码实现
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
//存放棋盘和皇后的数量
private static final int QUEEN_NUM = 8;
//存储最终结果
List<String> finalRes;
//存储皇后位置
List<Integer> nowRes;
public Main() {
finalRes = new ArrayList<>();
nowRes = new ArrayList<>();
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
Main m = new Main();
m.queueProblem(0);
while (cin.hasNext()) {
int i = cin.nextInt();
System.out.println(m.finalRes.get(i - 1));
}
}
public void queueProblem(int i) {
// 遍历当前行的所有单元格 以行为单元
for (int j = 0; j < QUEEN_NUM; j++) {
// 是否能够放置皇后
if (check(i, j)) {
nowRes.add(j);
if (i == QUEEN_NUM - 1) {
// 最后行放置完毕 放入空间
finalRes.add(listToString());
} else {
// 放置下一行
queueProblem(i + 1);
}
//回退到当前步骤,把皇后设置为0
nowRes.remove(i);
}
}
}
public boolean check(int i, int j) {
for (int x = 0; x < nowRes.size(); x++) {
int y = nowRes.get(x);
//检查列 检查右下 检查左下
if (y == j || Math.abs(i - x) == Math.abs(y - j)) {
return false;
}
}
return true;
}
public String listToString() {
String res = "";
for (int i : nowRes) {
res += i + 1;
}
return res;
}
}