题目描述:
解题思路:
刚做完leetcode岛屿系列的问题,这道题一看,就又是dfs的题,然后就试着写了一下,没AC,然后看自己的写法和正确写法的区别,发现自己已经基本写出来了,就是一些细节地方没有处理好,导致整个题没写出来。
错误代码:
class Solution {
public boolean exist(char[][] board, String word) {
char first = word.charAt(0);
char[] c = word.toCharArray();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == first)
return dfs(board, i, j, c, 0);
}
}
return false;
}
boolean dfs(char[][] board, int x, int y, char[] c, int ans) {
if (x < 0 || y < 0 || x >= board.length || y > board[0].length)
return false;
if(ans==c.length)
return true;
if (board[x][y] != c[ans])
return false;
ans++;
return dfs(board, x + 1, y, c, ans) ||
dfs(board, x - 1, y, c, ans) ||
dfs(board, x, y + 1, c, ans) ||
dfs(board, x, y - 1, c, ans);
}
}
首先总结下我的错误吧,一开始我想着两层for循环里面,先确定给定字符串的第一个字符,然后当找到第一个字符开始,在dfs。实际上这种想法是错误的,因为我要写一个dfs就是从没一个开始遍历,直到找到正确的,根本不需要if,再有就是要先if(dfs)在返回,不能直接返回dfs的返回值,因为在不停的搜索,可能第一次就return false了但是还没搜完。
在dfs方法里面,我忘记了回溯.还有ans(也就是自己定的下标)和c的长度匹配到什么情况下就return true,下次写的时候不能凭感觉写,一定要把思路理清楚。
AC代码:
public boolean exist(char[][] board, String word) {
char[] c = word.toCharArray();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if(dfs(board,i,j,c,0))
return true;
}
}
return false;
}
boolean dfs(char[][] board, int x, int y, char[] c, int ans) {
if (x < 0 || y < 0 || x >= board.length || y >= board[0].length||board[x][y] != c[ans])
return false;
if(ans==c.length-1)
return true;
char temp=board[x][y];
board[x][y]='.';
ans++;
boolean res=dfs(board, x + 1, y, c, ans) ||
dfs(board, x - 1, y, c, ans) ||
dfs(board, x, y + 1, c, ans) ||
dfs(board, x, y - 1, c, ans);
board[x][y]=temp;
return res;
}
大佬注解版
public boolean exist(char[][] board, String word) {
char first = word.charAt(0);
char[] c = word.toCharArray();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (dfs(board, c,i, j, 0))
return true;
}
}
return false;
}
boolean dfs(char[][] board, char[] word, int i, int j, int index) {
//边界的判断,如果越界直接返回false。index表示的是查找到字符串word的第几个字符,
//如果这个字符不等于board[i][j],说明验证这个坐标路径是走不通的,直接返回false
if (i >= board.length || i < 0 || j >= board[0].length || j < 0 || board[i][j] != word[index])
return false;
//如果word的每个字符都查找完了,直接返回true
if (index == word.length - 1)
return true;
//把当前坐标的值保存下来,为了在最后复原
char tmp = board[i][j];
//然后修改当前坐标的值
board[i][j] = '.';
//走递归,沿着当前坐标的上下左右4个方向查找
boolean res = dfs(board, word, i + 1, j, index + 1) || dfs(board, word, i - 1, j, index + 1) ||
dfs(board, word, i, j + 1, index + 1) || dfs(board, word, i, j - 1, index + 1);
//递归之后再把当前的坐标复原
board[i][j] = tmp;
return res;
}