目录
题目描述:
如图所示有一个 3X4 的迷宫,其中黑色方框代表墙,白色方框代表可通行,指定迷宫的入口和出口,计算出入口到出口的路径
解题思路:
1.先将迷宫地图看成二维数组,可以粗略认为数组下标为坐标轴,(涉及到数组就要保证数组下标不越界!!!)
2.怎么移动?数组横坐标纵坐标+1 或者 -1视为移动一步, 每次只能移动一步(横纵坐标只能加一次)
3.移动的方向最多4个方向,上下左右。
x-1 , y | ||
x , y-1 | x , y | x , y+1 |
x+1 , y |
4.可以在二维数组中 设置1为墙 0 为可以走的路
5.每走一步需要记录当前的坐标
6.走之前要判断所走的位置是否可走(数组下标越界 位置为1 等等)
算法代码:
package com.zgdx.maze;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Maze {
public static void main(String[] args) {
//获取地图 map
int [][] map = draw();
//获取起点位置和终点位置
int [] benAndEnd = begAndEnd();
//获取起点坐标
int x = benAndEnd[0];
int y = benAndEnd[1];
//获取地图长度
int len = map.length;
int wid = map[0].length;
//将终点设置为特殊的标记
map[benAndEnd[2]][benAndEnd[3]] = 9;
//用一个数组存储 走过的路线
int [][] runner = map;
//如果数组中走过了标记为8
//再来一个集合 存路径
List path = new ArrayList();
//每走一步都加一个当前的坐标
//path.add(x , y);
run(map , runner , path , len , wid , x , y);
//一共走了几步
System.out.println("一共走了" + path.size() + "步");
//走的路径
for (int i = 0; i < path.size(); i++) {
System.out.println(path.get(i));
}
}
/**
*
* @return 数组0、1为起点坐标 2、3为终点坐标
*/
public static int[] begAndEnd(){
int[] begAndEnd = new int[4];
//起点终点坐标
System.out.println("请输入起点 例:0,0");
Scanner s = new Scanner(System.in);
String begin = s.nextLine();
//将输入的字符以 , 分割 拆分成坐标
int [] begins = strToInt(begin , ",");
begAndEnd[0] = begins[0];
begAndEnd[1] = begins[1];
System.out.println("请输入终点 例:0,0");
String end = s.nextLine();
//将输入的字符以 , 分割 拆分成坐标
int [] ends = strToInt(end , ",");
begAndEnd[2] = ends[0];
begAndEnd[3] = ends[1];
return begAndEnd;
}
/**
*
* @return 返回绘制完成的地图
*/
public static int [][] draw(){
System.out.println("输入地图大小 例:3*4");
Scanner s = new Scanner(System.in);
String size = s.nextLine();
//将输入的字符串以*拆分成地图的长和宽
int [] maps = strToInt(size , "\\*");
//地图的二维数组 大小为输入的两个数字
int [][] map = new int[maps[0]][maps[1]];
System.out.println("输入墙的坐标 输入0为结束 例:0,2 1,0 1,2 0");
for ( ; ; ) {
String wall = s.nextLine();
//如果是0 结束输入
if ("0".equals(wall)){
break;
}
//将地图绘制上墙
map[strToInt(wall , ",")[0]][strToInt(wall , ",")[1]] = 1;
}
return map;
}
/**
*
* @param str 传入一个需要拆分的字符串
* @param split 传入一个拆分字符
* @return nums 拆分后转换成数字的数组
*/
public static int[] strToInt(String str, String split){
int [] nums = new int[2];
String [] strings = str.split(split);
nums[0] = Integer.parseInt(strings[0]);
nums[1] = Integer.parseInt(strings[1]);
return nums;
}
/**
*
* 使用递归分别走所有的方向
*/
public static void run(int[][] map , int [][] runner , List path , int len , int wid , int x , int y){
//判断当前位置是否可以走
if (x >= len || x < 0 || y >= wid || y < 0
|| map[x][y] == 1 || runner[x][y] == 8){
return;
}
//判断当前位置是不是已经到终点了
if (map[x][y] == 9){
return;
}
//可以走标记当前位置
runner[x][y] = 8;
//把当前位置坐标存在集合中
path.add(new Node(x , y));
//继续走
run(map , runner , path , len , wid , x+1 , y);
run(map , runner , path , len , wid , x-1 , y);
run(map , runner , path , len , wid , x , y+1);
run(map , runner , path , len , wid , x , y-1);
//清除失败的痕迹
// runner[x][y] = 0;
}
}
Node类体代码:
package com.zgdx.maze;
public class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Node{" +
"x=" + x +
", y=" + y +
'}';
}
}
问题总结:
- 把坐标轴替换成数组 在数组中设置可以走的地方 和墙壁
- 在当前位置是最多有4个方向可以走的 上下左右 让程序依次递归 也就是嗲用方法压栈
- 其实还有一些不足 后续再说 正在改进 比如最优解 最短路径问题 等等