1. 问题描述
假设有一个如图所示的 8x7 迷宫,实现找到从起点位置走到终点位置的路线
2. 思路
可以使用递归解决:
- 整个迷宫是一个二维数组,假设初始不能走的位置为 1 ,没有走的位置为 0 ,走过的位置为 2 ,走过但无法走通的位置为 3 ;
- 且采用 下 --> 右 --> 上 --> 左 的策略来走迷宫,即先往下走,如果下走不通,则往右走,再走不通,走上,再不行,则走左,如果都走不通,则回溯(回到前一个位置)
- 按照策略递归遍历每一个位置,直到找到路线或者没有路线
3. 代码实现
代码如下:
/**
* 迷宫回溯问题解决(递归):
* 1. map 表示地图,(i,j) 表示开始出发的位置;
* 2. 如果小球找到 map[6][1] 位置,说明通路找到;
* 3. 当 map[i][j] :
* 为 0 时则表示该点没有走过;为 1 时则表示为墙;
* 为 2 时表示通路可以走;为 3 时则表示已经走过,但是无法走通;
* 4. 在走迷宫前,需要定一个策略:
* 下 --> 右 --> 上 --> 左
* 即:先往下走,如果下走不通,则往右走,再走不通,走上,再不行,则走左
* 如果都走不通,则回溯
*
* @param map 迷宫地图
* @param i 小球寻路的开始位置横向索引
* @param j 小球寻路的开始位置纵向索引
* @return 该位置能否走通(能返回 true ,不能返回 false )
*/
public static boolean setWay(int[][] map, int i, int j) {
//如果走过终点位置,则表示通过迷宫路线已经找到,结束递归
if (map[6][1] == 2) {
return true;
} else {
//如果迷宫当前位置为 0 ,则表示当前位置没有走过
if (map[i][j] == 0) {
//走过当前位置,则将当前位置置为 2
map[i][j] = 2;
//在当前位置按照策略走迷宫
if (setWay(map, i + 1, j)) {
return true;
} else if (setWay(map, i, j + 1)) {
return true;
} else if (setWay(map, i - 1, j)) {
return true;
} else if (setWay(map, i, j - 1)) {
return true;
} else {
//如果当前位置上下左右都走不通,则置为 3 ,且返回 false
//返回 false 表示当前位置的 setWay() 方法结束,回到上一个位置的 setWay() 方法
map[i][j] = 3;
return false;
}
} else {
//如果当前位置为 1,2 或 3 ,则返回 false
//返回 false 表示当前位置的 setWay() 方法结束,回到上一个位置的 setWay() 方法
return false;
}
}
}
方法执行图示:
4. 测试
代码如下:
public static void main(String[] args) {
//创建二维数组,模拟迷宫
int[][] map = new int[8][7];
Arrays.fill(map[0], 1);
Arrays.fill(map[7], 1);
for (int i = 1; i < map.length - 1; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
map[2][2] = 1;
map[2][6] = 1;
map[3][1] = 1;
map[3][3] = 1;
map[4][4] = 1;
map[5][2] = 1;
map[6][3] = 1;
//遍历打印初始迷宫
for (int[] ints : map) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
System.out.println("-------------------------------------");
//执行迷宫回溯法
setWay(map, 1, 1);
//打印寻路结束后的迷宫
for (int[] ints : map) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
}
测试结果: