矩阵中的路径(中等)
2020年8月13日
题目来源:力扣
解题
这是一道经典的DFS题,个人认为创新点在于初始位置的不确定性
思路如下:
1.因为初始位置不确定,一开始要循环数组,选择初始点
2.进入DFS遍历时,判断当前坐标的字符是否与目标的字符相等,若不相等直接返回
3.题目定义可以从四个方向到下一个点,那么尝试四种方向,如果过界或已经走过的坐标就不前进,尝试前进,那就把前进点进行标识,前进后不能匹配将回溯,那么前进点设置成未标识的状态;若匹配,则不回溯,进行下一次DFS的遍历
4.DFS最终判断条件为当前步数等于目标字符串长度
- DFS
创建和原数组大小一致的flag数组来标记每个点是否走过,在每次进入DFS后,匹配成功则标记上这个点,匹配失败则在回溯时需要设置这个点为未标记。
同时,因为初始位置的不确定,一开始就有个大循环,为了不让上个flag数组对之后造成影响,应该在每次找到初始点时就创建
class Solution {
//定义函数前进的四个方向
int[][] dxy={{0,1},{1,0},{0,-1},{-1,0}};
//标志数组
boolean[][] flag;
public boolean exist(char[][] board, String word) {
char[] words=word.toCharArray();
int x_len=board.length;
if(x_len==0) return false;
int y_len=board[0].length;
if(y_len==0) return false;
//遍历数组
for(int i=0;i<x_len;i++){
for(int j=0;j<y_len;j++){
//创建标志数组
flag=new boolean[x_len][y_len];
if(dfs(i,j,x_len,y_len,0,board,words)) return true;
}
}
return false;
}
//参数:当前坐标x值,当前坐标y值,总行数,总列数,当前步数,字符数组board,字符数组words
private boolean dfs(int cur_x,int cur_y,int total_x,int total_y,int foot,char[][] board,char[] words){
if(board[cur_x][cur_y]!=words[foot]){
return false;
}
//字符串长度相等,说明匹配成功
if(foot==words.length-1) {
return true;
}
//标记点已走过
flag[cur_x][cur_y]=true;
for(int i=0;i<4;i++){
int new_x=cur_x+dxy[i][0];
int new_y=cur_y+dxy[i][1];
//保证不过界且未被走过
if(new_x>=0&&new_x<total_x&&new_y>=0&&new_y<total_y&&flag[new_x][new_y]==false){
if(dfs(new_x,new_y,total_x,total_y,foot+1,board,words)) return true;
//回溯
flag[new_x][new_y]=false;
}
}
return false;
}
}
- DFS优化
上个做法有个弊端就是每次都要创建flag新数组,进行优化
我们在每次进入DFS时,都首先会判断是否与目标字符相等,那如果我暂时性的把数组的字符改成不是字母的,那在每次进入时就都会判断为不相等而返回,就相当于进行了标志。最后也要记得进行回溯,不影响之后的结果。
class Solution {
//定义函数前进的四个方向
int[][] dxy={{0,1},{1,0},{0,-1},{-1,0}};
public boolean exist(char[][] board, String word) {
char[] words=word.toCharArray();
int x_len=board.length;
int y_len=board[0].length;
//遍历数组
for(int i=0;i<x_len;i++){
for(int j=0;j<y_len;j++){
if(dfs(i,j,x_len,y_len,0,board,words)) return true;
}
}
return false;
}
//参数:当前坐标x值,当前坐标y值,总行数,总列数,当前步数,字符数组board,字符数组words
private boolean dfs(int cur_x,int cur_y,int total_x,int total_y,int foot,char[][] board,char[] words){
if(board[cur_x][cur_y]!=words[foot]){
return false;
}
//字符串长度相等,说明匹配成功
if(foot==words.length-1) {
return true;
}
//临时记录
char temp=board[cur_x][cur_y];
board[cur_x][cur_y]='*';
for(int i=0;i<4;i++){
int new_x=cur_x+dxy[i][0];
int new_y=cur_y+dxy[i][1];
//保证不过界
if(new_x>=0&&new_x<total_x&&new_y>=0&&new_y<total_y){
if(dfs(new_x,new_y,total_x,total_y,foot+1,board,words)) return true;
}
}
board[cur_x][cur_y]=temp;
return false;
}
}