DFS! 给我冲
Posted 短腿Cat
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DFS! 给我冲相关的知识,希望对你有一定的参考价值。
No.剑指 Offer 12 矩阵中的路径
给定一个 m x n
二维字符网格 board
和一个字符串单词 word
。如果 word
存在于网格中,返回 true
;否则,返回 false
。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。
示例 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
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
board
和word
仅由大小写英文字母组成
注意:本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/
思路分析
dfs意思就是深度优先搜索
其实,dfs是最像人的平常思维的一种方法,就是一个一个来匹配
可以想象,如果你来人为判断这道题,该怎么判断呢?
- 首先在board里找到一个和word中的第一个字符相等的字符a(变量名)
- 从a字符的四个方向(上下左右)找到和word中第二个字符相等的字符b(变量名)
- 再从b字符的三个方向(除了刚刚从a转移过来的那一方向)找到word第三个字符相等的字符(变量名)
- …(中途如果有不匹配,则退回到上一个字符,再从其他方向尝试)
- 最后判断到最后一个字符,然后成功找到,就可以啦
注:正如上述的3,在判断过程中,不能往之前判断过的路径判断,所以判断过的地方我们就暂时置为一个谁都不可能相等的标记,会在如下代码中体现出来。
所以dfs往往是最好理解的一类题型,给熟练的大佬写的话,可能思考过程都不要,就是对着键盘一顿敲,几分钟就写完了。如果感觉将这种简单的思维变成代码比较困难,不要紧,说明题目练的还不够,多看几遍优秀的代码多敲几遍,也自然就会了(当然我写的挺垃圾的,提供一种思路吧)
Java代码
class Solution {
boolean flag = false;
int[] m = new int[]{1, 0, -1, 0};
int[] n = new int[]{0, 1, 0, -1};
public boolean exist(char[][] board, String word) {
int row = board.length;
int col = board[0].length;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (flag) {
break;
}
dfs(board, word, row, col, i, j, 0);
}
}
return flag;
}
private void dfs(char[][] board, String word, int row, int col, int i, int j, int temp) {
/* 剪枝 */
if (flag) {
return;
}
/* 防越界 */
if (!(i >= 0 && i < row && j >= 0 && j < col)) {
return;
}
/* 不相等的回退 */
if (board[i][j] != word.charAt(temp)) {
return;
}
/* 最终情况正确的处理 */
if (temp == word.length() - 1) {
flag = true;
return;
}
/* 将该点暂时打上标记 */
char c = board[i][j];
board[i][j] = '*';
for (int k = 0; k < 4; k++) {
dfs(board, word, row, col, i + m[k], j + n[k], temp + 1);
}
/* 解除标记 */
board[i][j] = c;
}
}
喜欢的话点个赞呗~
以上是关于DFS! 给我冲的主要内容,如果未能解决你的问题,请参考以下文章