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
  • boardword 仅由大小写英文字母组成

 

注意:本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/

思路分析

dfs意思就是深度优先搜索
其实,dfs是最像人的平常思维的一种方法,就是一个一个来匹配
可以想象,如果你来人为判断这道题,该怎么判断呢?

  1. 首先在board里找到一个和word中的第个字符相等的字符a(变量名)
  2. 从a字符的四个方向(上下左右)找到和word中第个字符相等的字符b(变量名)
  3. 再从b字符的三个方向(除了刚刚从a转移过来的那一方向)找到word第三个字符相等的字符(变量名)
  4. …(中途如果有不匹配,则退回到上一个字符,再从其他方向尝试)
  5. 最后判断到最后一个字符,然后成功找到,就可以啦

注:正如上述的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! 给我冲的主要内容,如果未能解决你的问题,请参考以下文章

[Edp] lcLCP 07. 传递信息(暴搜+dp求方案+矩阵乘法+好题)

DFS习题复习

dfs序

树形DP常见基本题型

树形DP常见基本题型

9509 开灯(dfs)