矩阵中的路径-Java实现
矩阵中的路径
http://www.nowcoder.com/questionTerminal/c61c6999eecb4b8f88a98f66b273a3cc
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
讲讲为什么用DFS,而不能用BFS (个人看法,有误请批!)
这道题首先看出是DFS(深搜)问题,(为何是DFS,DFS就是用来不停探寻下一步,直至能否到达目的点,而另一种是BFS(广搜),BFS是用来找到源点到终点的最短路径。如果用BFS求解这道题,嗯?确定能用吗?BFS是以源点向四周扩散,以最短的扩散次数找到源点,听起来好像可以,我们可以一次次扩散找到路径中的每一个点,但是一般的BFS扩散一次,会把走过的结点标志为不可以走,那么假如第一个结点A四周扩散一次,四周走过,恰巧右方是第二个结点B,下方是最后一个结点E,那么以B怎么扩散都不能访问到E,因为E被走过,B怎么走都走不到E,所以个人觉得BFS不能用来解决这道题,只能用DFS一条路走到黑的方式来解决)
这道题就是以矩阵中的每一个点作为为起点去执行一次DFS。而DFS的执行过程就是:
- 每次执行DFS先判断走过的路径是不是等于要求的路径,是就返回结果true,不是就继续找。
- 先判断当前点是否可走,不是,则返回上一层;是就顺时针探寻下一个方位的结点(上、右、下、左),以下一个方位结点进行DFS,如果方位都探完了还找不到路径,那么当前节点不可能是路径结点之一,只能返回上一层。
Java代码实现
public class Solution {
private boolean visited[] = null;//标志每个位置是否走过,true走过,false没走过
public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
if (matrix == null || str == null || str.length > matrix.length || rows * cols != matrix.length)
//进行非法性判断
return false;
//初始化visited数组
visited = new boolean[rows * cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
//以每个结点作为起始节点去dfs
if (dfs(matrix, i, j, rows, cols, str, 0))
return true;
}
}
//没有找到
return false;
}
/**
* @param matrix 地图
* @param x 起点x
* @param y 起点y
* @param rows 行数
* @param cols 列数
* @param str 所求路径
* @param len 当前已经找到路径的长度
* @return
*/
private boolean dfs(char[] matrix, int x, int y, int rows, int cols, char[] str, int len) {
if (len >= str.length) {
//找到要求的路径
return true;
} else {
//路径长度小于要求的长度,还得继续寻找
if (x >= 0 && x <= rows - 1 && y >= 0 && y <= cols - 1 && visited[x * cols + y] == false && matrix[x * cols + y] == str[len]) {
//当前结点是路径节点之一
visited[x * cols + y] = true;//把当前结点的标志位设为true,证明走过了
//寻找下一方位
int dict = 0;
int x1 = 0, y1 = 0;
while (dict <= 3) {
switch (dict) {
case 0: x1 = x - 1; y1 = y; break;
case 1: x1 = x ; y1 = y + 1; break;
case 2: x1 = x + 1; y1 = y; break;
case 3: x1 = x ; y1 = y - 1; break;
}
if(dfs(matrix, x1, y1, rows, cols, str, len + 1))//判断下一个方位能否找到路径
return true; //能,直接返回
dict ++;//不能,找下一方位
}
//不能从当前结点找不到路径,那就回溯,把当前结点标志位设为false
visited[x * cols + y] = false;
return false;//返回失败
} else{
//当前结点不是要找的路径,直接回溯
return false;
}
}
}
}
查看14道真题和解析