经典DFS+回溯:LC79
使用深度优先搜索(DFS)和回溯的思想实现。
关于判断元素是否使用过,我用了一个二维数组visited对使用过的元素做标记
我将每步的步骤详细解释了一下:更方便复习以及参考。
public class Solution {
private static final int [][] dirs={
{-1,0},{0,-1},{1,0},{0,1}};//记录方向用
private int rows;//记录数组行数
private int cols;//记录数组列数
private int len;//记录字符串长度
private boolean[][] visited;//布尔数组,用来储存是否经过(标记过)
private char[] charArray;
private char[][] board;
private boolean exist (char[][] board,String word){
rows=board.length;
if(rows==0){
return false;
}
cols=board[0].length;
visited=new boolean[rows][cols];//创建一个初始值为false的布尔数组,大小与board数组一样,用于记录路径
this.len=word.length();//记录字符串长度
this.charArray=word.toCharArray();//将字符串转换为一维字符数组:用于
this.board=board;
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
if(dfs(i,j,0)){//这是递归寻找
return true;
}
}
}
return false;
}
//递归函数,begin是用于取字符串数组的字母的下标
private boolean dfs(int x,int y,int begin){
if(begin==len-1){//如果刚好等于字符串的大小
return board[x][y]==charArray[begin];//返回两个相等的true,==,继续执行
}
if(board[x][y]==charArray[begin]){//这个位置的字母如果正好和字符数组的相等,
visited[x][y]=true;//记录为true
for(int[]dir:dirs){//开始找下一个符合的位置,从4个方向开始
int newX=x+dir[0];//这里有点不理解dir【0】,循环,好像是代表一个dir(1,0)的取1和0,然后就右边的方向
int newY=y+dir[1];//取好新的方向后,就去判断是否越界,是否访问过
if(inArea(newX,newY)&&!visited[newX][newY]){//
if(dfs(newX,newY,begin+1)){//取好新的方向,没有越界,并且这个地方没有被用(就是不是之前匹配好的字符串的位置),然后进行新的递归,最终返回一个正确的答案
return true;
}
}
}
visited[x][y]=false;//不等于就返回false,回溯
}
return false;
}
private boolean inArea(int x,int y){
return x>=0&&x<rows&&y>=0&&y<cols;//这是规定边界,满足就返回ture,继续执行下面的
}
}