解法一:(回溯法)建立一个二维数组,标识该位置的数是否已经遍历,0为未遍历,1为已遍历;每次回溯函数都在已经找到的数的四周找word中的下一个字母,回溯标志为used[i][j]=0
java
class Solution {
// 建立两个数组,以便遍历相邻的单元格
int[] row = new int[]{0,1,0,-1};
int[] col = new int[]{1,0,-1,0};
public boolean exist(char[][] board, String word) {
// 建立一个二维数组,标识该位置的数是否已经遍历,0为未遍历,1为已遍历
int[][] used = new int[board.length][board[0].length];
boolean result = false;
for(int i=0; i<board.length; i++){
for(int j=0; j<board[0].length; j++){
if(board[i][j]==word.charAt(0)){
used[i][j]=1;
result = backtrack(board, word, used, i, j, 1); // 1表示开始找word的第1个数
used[i][j]=0; // 记得回溯
if(result==true){
return true;
}
}
}
}
return result;
}
public boolean backtrack(char[][] board, String word, int[][] used, int i, int j, int num){
if(num >= word.length()){
// 已经找完了
return true;
}
boolean result = false;
for(int n=0;n<4;n++){
int x = i + row[n];
int y = j + col[n];
if(x>=0 && x<board.length && y>=0 && y<board[0].length && used[x][y]==0 && board[x][y]==word.charAt(num)){
used[x][y]=1;
result = backtrack(board, word, used, x, y, num+1);
if(result==true){
return true;
}
used[x][y]=0; // 回溯
}
}
return result;
}
}
注意:
- 在非回溯函数
exist()
中,也要记得回溯:used[i][j]=0
- 遍历相邻元素时,不可以
j += idy
,这样会导致j变化跳过几个数不比较;要int x = i + row[n]
- 不能双for:
for(int idx:row){for(int idy:col){...}}
,这样会导致判断一些不是相邻元素;要for(int n=0;n<4;n++)
并取row[n]
和col[n]