剑指 Offer 12. 矩阵中的路径
难度:中等
题目描述
解题思路
题目给的标签是动态规划,然后就一直顺着动态规划的思路想了好久,还是觉得不对啊,这不就是图的搜索嘛,动态规划感觉不好做。用dfs回溯感觉清晰很多
参考题解:面试题12. 矩阵中的路径(深度优先搜索 DFS ,清晰图解)
找到一个等于目标值的开始搜索,每次搜索上下左右四个相邻方向,剪枝条件是下标越界或者不等于目标值,当整个单词都匹配完的时候返回true;
要注意的是,回溯法在设置完状态,然后递归之后,还要状态回溯,清楚这一步标记的状态
/*
* 剑指 Offer 12. 矩阵中的路径
* 2020/7/18 dfs回溯法
*/
public boolean exist(char[][] board, String word) {
int m = board.length;
int n = board[0].length;
boolean[][] visit = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(board[i][j] == word.charAt(0)) { //找到起点,开始搜索
if(dfsExist(board,word,i,j,0,m,n,visit)) //进行dfs搜索
return true;
}
}
}
return false;
}
public boolean dfsExist(char[][] board,String word,int i,int j,int index,int m ,int n,boolean visit[][]) {
if(index == word.length()) //如果匹配完了整个单词
return true;
if(i >= m || i < 0 || j >= n || j < 0 || visit[i][j] || board[i][j] != word.charAt(index))
return false;
visit[i][j] = true; //记录已经访问
boolean re = dfsExist(board, word, i+1, j, index+1, m, n,visit)
|| dfsExist(board, word, i-1, j, index+1, m, n,visit)
|| dfsExist(board, word, i, j+1, index+1, m, n,visit)
|| dfsExist(board, word, i, j-1, index+1, m, n,visit);
if(re) {
return true;
}else {
visit[i][j] = false;
return false;
}
}
可以优化的地方是直接用原数组来标记是不是已经访问过,访问的时候设置成一个特殊字符,回溯的时候设置回去。
public boolean exist(char[][] board, String word) {
int m = board.length;
int n = board[0].length;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(board[i][j] == word.charAt(0)) { //找到起点,开始搜索
if(dfsExist(board,word,i,j,0,m,n)) //进行dfs搜索
return true;
}
}
}
return false;
}
public boolean dfsExist(char[][] board,String word,int i,int j,int index,int m ,int n) {
if(index == word.length()) //如果匹配完了整个单词
return true;
if(i >= m || i < 0 || j >= n || j < 0 || board[i][j] == '#' || board[i][j] != word.charAt(index))
return false;
char temp = board[i][j];
board[i][j] = '#'; //记录已经访问
boolean re = dfsExist(board, word, i+1, j, index+1, m, n)
|| dfsExist(board, word, i-1, j, index+1, m, n)
|| dfsExist(board, word, i, j+1, index+1, m, n)
|| dfsExist(board, word, i, j-1, index+1, m, n);
if(re) {
return true;
}else {
board[i][j] = temp;
return false;
}
}