矩阵中的路径
1、参考资料
https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/
2、题目要求
题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
3、代码思路
假设二维字符数组为:
char[][] board = {
{'a', 'b', 'c', 'e'},
{'s', 'f', 'c', 's'},
{'a', 'd', 'e', 'e'},
};
待寻找的路径为 "bfce"
- 一看到这种寻找路径的题目,想都不用想,肯定是用深度优先搜索
- 首先给定一个起点,比如说
row = 0; col = 1
,则起点board[row][col] = 'b'
,首先,我们从起点向上、向下、向左、向右搜索,如果搜索不到目标字符则返回false
,表示此路不通,如果能够搜索到目标字符,则在目标字符的基础上,继续向上、向下、向左、向右搜索 - 如果搜索到最后一个字符
e
都能匹配上,则说明此路畅通,返回true
,表示找到目标路径 - 从上面的过程来看,这明显就是一个递归搜索的过程,
"bfce"
这条路径到底能不能走通,则需要走到字符e
(递归至最深层),才能知道此路径能走通;如果当前位置向上、向下、向左、向右都不能走通,则此路不通,需要回溯至上一层
4、代码实现
代码
/**
* @ClassName RectanglePathDemo
* @Description TODO
* @Author Heygo
* @Date 2020/8/29 10:21
* @Version 1.0
*/
public class RectanglePathDemo {
public static void main(String[] args) {
char[][] board = {
{'a', 'b', 'c', 'e'},
{'s', 'f', 'c', 's'},
{'a', 'd', 'e', 'e'},
};
String word = "bcce";
boolean exist = exist(board, word);
System.out.println(exist);
}
/**
* 判断 board 数组中是否存在目标路径 word
* @param board 字符数组
* @param word 待匹配的字符串
* @return 是否找到目标路径
*/
public static boolean exist(char[][] board, String word) {
// Guard Safe
if (word == "" || word == null) {
return false;
}
// 遍历二维数组,以每个字符为起点,尝试深度遍历,找到目标路径
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
// 如果找到则返回 true
if (dfs(board, word, i, j) == true) {
return true;
}
}
}
// 走到这里,说明没有找到目标路径,返回 false
return false;
}
/**
* 深度遍历,在 board 数组中寻找目标 word 路径
* @param board 字符数组
* @param word 待匹配的字符串
* @param row 当前行索引
* @param col 当前列索引
* @return 深度遍历的结果,即是否成功找目标字符串的路径
*/
public static boolean dfs(char[][] board, String word, int row, int col) {
// 如果 word == "",表示匹配到全部字符,找到路径,返回 true
if ("".equals(word)) {
return true;
}
// 否则,取出字符串中第一个字符
Character destChar = word.charAt(0);
// 1.如果行指针和列指针超出数组界限,或者
// 2.如果 board[row][col] 元素不是目标字符
// 则返回 false,表示没找到
if (row < 0 || row >= board.length || col < 0 || col >= board[0].length || board[row][col] != destChar) {
return false;
}
// 保存当前位置的字符
char tepChar = board[row][col];
// 将当前元素的字符修改为 '$'(不是字母即可)
board[row][col] = '$';
// 走到这里,就说明当前字符符合要求,则继续向上、向下、向左、向右进行深度遍历
boolean result =
dfs(board, word.substring(1), row - 1, col) ||
dfs(board, word.substring(1), row + 1, col) ||
dfs(board, word.substring(1), row, col - 1) ||
dfs(board, word.substring(1), row, col + 1);
// 回溯后恢复原位置的字符
board[row][col] = tepChar;
// 返回深度遍历的结果
return result;
}
}