Java算法---华为oj迷宫问题求解(深度优先搜索)
来源:互联网 发布:java培训课程体系 编辑:程序博客网 时间:2024/06/05 00:15
自己花了好长时间学习了深度优先搜索算法,受益颇多,网上许多资料都看不太懂,最后自己按着那个思想一步一步实现了,分享一下,以华为oj上的迷宫问题为例来说一下:
问题描述:
定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5×5数组下所示:
int maze[5][5]={ 0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0, };
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。
Input 一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。 Output 左上角到右下角的最短路径,格式如样例所示。
Sample Input 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0
Sample Output (0, 0) (1, 0) (2, 0) (2, 1) (2, 2) (2, 3) (2, 4) (3, 4) (4, 4)
输入描述:
输入两个整数,分别表示二位数组的行数,列数。再输入相应的数组,其中的1表示墙壁,0表示可以走的路。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
输出描述:
左上角到右下角的最短路径,格式如样例所示。
输入例子:
5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0
输出例子:
(0,0) (1,0) (2,0) (2,1) (2,2) (2,3) (2,4) (3,4) (4,4)
之前我们求最短路径用的广度优先搜索,这个题看似是最短路径问题,其实不是,因为题目上说了只有一条通路,而且还要输出这个路径,那么深度优先搜索比较合适,当然广度优先搜索也可以(可以看我的下一篇博客哦,会用广搜方法实现)。深度优先搜索的思想是沿着一个方向搜到底,如果行不通,则返回来试其他的路径。就一直这样直到找到一条通路输出就可以了。其实这个思想网上一大堆,但是具体怎么实现呢?下面我贴上自己的代码,代码中会有详细的注释:
<span style="font-family:SimSun;font-size:18px;">import java.util.Scanner;import java.util.Stack;public class Main { public static void main(String args[]){ Scanner sc=new Scanner(System.in); while (sc.hasNext()) { int m = sc.nextInt(); int n = sc.nextInt(); int[][] map = new int[m][n];//定义一个Map矩阵,用来保存地图 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { map[i][j] = sc.nextInt();//输入地图 } } int[][] dir = {{1, 0}, {0, 1}};//定义两个方向横着走或者竖着走(题目中说只走这两个方向,当前也可以定义多个方向) Stack<Node> stack = new Stack<Node>();//定义一个栈,保存路径 int[][] visited = new int[m][n];//标记是否被访问,这个要和Map大小对应 Node start = new Node(0, 0);//定义起始位置 Node end = new Node(m - 1, n - 1);//定义目的位置 visited[start.x][start.y] = 1;//将起始点标记为访问 stack.push(start);//将起始点加入队列 while (!stack.isEmpty()) {//如果对了为空了还没有找到解,说明就没有通路,当然本题不存在无解,题目上说了一定存在一个通路。 boolean flag = false;//标记是否找了一个方向 Node pek = stack.peek();//获取栈顶元素,注意不需要出栈 if (pek.x == end.x && pek.y == end.y) {//如果到达目的地则跳出循环 break; } else { for (int i = 0; i < 2; i++) {//循环两个方向 Node nbr = new Node(pek.x + dir[i][0], pek.y + dir[i][1]);//找到当前位置的邻居位置坐标并判断是否合法 if (nbr.x >= 0 && nbr.x < m && nbr.y >= 0 && nbr.y < n && map[nbr.x][nbr.y] == 0 && visited[nbr.x][nbr.y] == 0) {//判断邻居节点是否合法 stack.push(nbr);//合法将邻居位置加入栈 visited[nbr.x][nbr.y] = 1;//并标记该节点已经访问 flag = true;//找到了一个方向 break;//找到了就停止循环,顺着这个方向一直搜索 } } if (flag) {//找到了方向,就不用执行下面的出栈,沿着这个方向一直搜下去 continue; } stack.pop();//如果两个方向都不能通过,则出栈。 } } Stack<Node> stkRev = new Stack<Node>();//将路径反过来,因为栈中输出的路径是反的 while (!stack.isEmpty()) { stkRev.push(stack.pop()); } while (!stkRev.isEmpty()) { System.out.println("(" + stkRev.peek().x + "," + stkRev.peek().y + ")"); stkRev.pop(); } } }}class Node{ int x; int y; Node(int x,int y){ this.x=x; this.y=y; }}</span>
上面是代码,注解很详细,应该可以看懂,我的下一篇博客将会讲到怎样用广度优先搜索实现这个问题,通过这个例子尽量将广度和深度弄清楚,可以解决好多问题。呵呵。有什么问题欢迎提问。
我的这一篇博客中讲到了广度优先搜索的用法,也可以学习一下广搜。Java算法---求面积
- Java算法---华为oj迷宫问题求解(深度优先搜索)
- Java算法---华为oj迷宫问题求解(广度优先搜索)
- Matlab 深度优先搜索求解迷宫问题
- 深度优先搜索求解迷宫问题
- 栈:深度优先搜索与回溯算法求解迷宫
- 算法:堆栈与深度优先搜索(迷宫问题)
- 算法:堆栈与深度优先搜索(迷宫问题)
- 深度优先搜索算法(迷宫最短路径问题)
- 求解:栈的应用 深度优先搜索:迷宫问题
- 深度优先搜索DFS(迷宫问题)
- 迷宫问题(深度优先搜索)
- 深度优先搜索-求解迷宫解空间
- 迷宫问题(maze problem)——深度优先(DFS)与广度优先搜索(BFS)求解
- Matlab 广度优先搜索求解迷宫问题
- 广度优先搜索求解迷宫问题
- 广度优先搜索求解迷宫问题
- 利用深度优先搜索算法和广度优先搜索算法解迷宫问题
- 深度优先搜索(堆栈)解决走迷宫问题
- 关于火狐的模糊查询分页乱码问题
- classpath、path、JAVA_HOME的作用及JAVA环境变量配置
- 关于UIImageView的显示问题——居中显示或者截取图片的中间部分显示
- Ext.js5(弹出搜索表单)(给一个面板添加数据)(34)
- 普天同庆
- Java算法---华为oj迷宫问题求解(深度优先搜索)
- iOS一些常用动画总结
- 编码以及计算机的发展
- 验证码实例
- MapReduce 算法设计-Local Aggregation
- QString和String相互转换
- Bootstrap快速学习笔记(2)表单系列之一
- Windows下Redis的安装使用
- 试题02 数字分类