1、判断一个迷宫是否有出口
这个题目是我自己编的,leetcode上并没有这样的题目。为了锻炼自己的DFS,这个题目应该还是比较简单的,用深搜就可以完成,和之前做的max area of island有异曲同工之妙。
poll出迷宫问题:
、
如图所示的迷宫,0代表可以走,1代表有墙。要求从左上角到右下角是否有一条路可以走完。如何判断这个迷宫内是否有路。代码如下:
1 boolean res = false;
2 int[] dest;
3 int[][] grid;
4 boolean[][] visited;
5 public boolean can(int[][] grid, int[] start, int[] dest){
6 boolean[][] visited = new boolean[grid.length][grid[0].length];
7 this.dest = dest;
8 this.grid = grid;
9 this.visited = visited;
10 helper(start[0],start[1]);
11 return res;
12 }
13
14 private void helper(int i, int j) {
15 if ( i == dest[0] && j == dest[1] ) res=true;
16 visited[i][j] = true;
17 if ( cango(i-1,j) ) helper(i-1,j);
18 if ( cango(i+1,j) ) helper(i+1,j);
19 if ( cango(i,j-1) ) helper(i,j-1);
20 if ( cango(i,j+1) ) helper(i,j+1);
21 }
22
23 public boolean cango(int i, int j){
24 if ( i < 0 || j < 0 || i >= grid.length || j >= grid.length) return false;
25 if ( grid[i][j] == 1 || visited[i][j] ) return false;
26 return true;
27 }
start数组时起始位置,end数组是终止位置。注意visited数组必不可少,记录走过的位置,已经走过的就不能再走了,否则就会陷入死循环。
这里先用一个cango函数来判断下一步是否可走,其实可以进行合并,简化一下:
1 boolean res = false;
2 int[] dest;
3 int[][] grid;
4 boolean[][] visited;
5 public boolean can(int[][] grid, int[] start, int[] dest){
6 boolean[][] visited = new boolean[grid.length][grid[0].length];
7 this.dest = dest;
8 this.grid = grid;
9 this.visited = visited;
10 newhelper(start[0],start[1]);
11 return res;
12 }
13
14 private void newhelper(int i, int j ){
15 if ( i < 0 || j < 0 || i >= grid.length || j >= grid.length) return ;
16 if ( grid[i][j] == 1 || visited[i][j] ) return ;
17 if ( i == dest[0] && j == dest[1] ) res=true;
18 visited[i][j] = true;
19 newhelper(i-1,j);
20 newhelper(i+1,j);
21 newhelper(i,j-1);
22 newhelper(i,j+1);
23 }
我自己测试了几组情况,是正确的。不知道其他的情况是不是正确。
2、记录迷宫正确路径
现在问题变成这样,首先判断迷宫中能否有正确的道路,如果有的话,找出最短的那个道路。
因为要保存道路,所以一定要用一个数据结构来保存路径,栈是最好的。因为栈后进先出的特性,使得栈很适合数据的迭代。这里用两个栈来简单做一下,第一个栈stack1保存节点的行,第二个栈保存节点的列,两个栈就确定一个节点。
因为找的是最短路径,所以可以使用BFS算法。
来源:oschina
链接:https://my.oschina.net/u/4287266/blog/3891412