剑指offer题解汇总 Java实现
https://blog.csdn.net/guliguliguliguli/article/details/126089434
本题链接
题目
题目主要信息
- 矩阵中上下左右随便移动,找到给定字符串的路径
- 访问可以重复,但是作为路径不能往回走
方案 深度优先搜索
递归与回溯
递归是一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。因此,递归过程,最重要的就是查看能不能将原本的问题分解成更小的子问题,这是使用递归的关键。
如果是线性递归,子问题直接回到父问题不需要回溯,但是如果是树型递归,父问题有很多分支,需要回到父问题,再进入父问题的另一个子问题。因此,回溯是指在递归过程中,从某一分支的子问题回到父问题,进入父问题的另一个子问题分支,因为有时候进入第一个子问题的时候,修改过一些变量,因此回溯的时候会要求改回父问题时的状态才能进入另一个子问题分支。
来自陈玉福老师《算法讲义》:
回溯法采用深度优先搜索的方式,朝纵深方向搜索,直至达到问题的一个可行解,或经判断不会达到问题的可行解或最优解时,停止向前搜索,并沿原路返回到该路径上最后一个还可扩展节点。然后,从该节点出发朝新的方向纵深搜索。
思路
首先在二维矩阵中找到起点,然后检查起点的上、下、左、右四个方向,看是否有满足条件的路径,有的话,则不断深入
在dfs(int x,int y,int pos)方法中,pos表示字符串的下标,即当前遍历到字符串的第几个位置
- 如果已经找到一条路线,return
- 如果成功找到了第一条路线,则设置isFind遍历为true(不会再继续查找下去),return
- 如果坐标越界,return
- 如果当前位置已经访问过了,return
- 如果当前访问的x,y位置的字符刚好与字符串中pos位置上的字符一致,则以该位置为中心,继续检查上、下、左、右四个方向
- …
代码
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* @param matrix char字符型二维数组
* @param word string字符串
* @return bool布尔型
*/
private char[][] map;
private boolean[][] vis;
private String way;
private boolean isFind;
public boolean hasPath(char[][] matrix, String word) {
map = matrix;
vis = new boolean[matrix.length][matrix[0].length];
way = word;
//获得字符串的第一个字符,找到起始位置
char start = word.charAt(0);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
//找到起始位置
if (matrix[i][j] == start) {
isFind = false;
//初始化vis二维数组是false
for (int k = 0; k < matrix.length; k++) {
Arrays.fill(vis[k], false);
}
dfs(i, j, 0);
if (isFind) {
return true;
}
}
}
}
return false;
}
private void dfs(int x, int y, int pos) {
//已经找到路线
if (isFind) {
return;
}
//找到了路线
if (pos == way.length()) {
isFind = true;
return;
}
//越界,直接返回
if (x >= map.length || x < 0 || y >= map[0].length || y < 0) {
return;
}
//已经访问过
if (vis[x][y]) {
return;
}
//当前x,y位置的字符刚好是string字符串中的,则遍历它的上下左右方向
if (map[x][y] == way.charAt(pos)) {
vis[x][y] = true;
//向下
dfs(x + 1, y, pos + 1);
//向上
dfs(x - 1, y, pos + 1);
//向右
dfs(x, y + 1, pos + 1);
//向左
dfs(x, y - 1, pos + 1);
vis[x][y] = false;
}
}
}