LeetCode hot100-79.单词搜索

这道题是属于回溯类型的题目。

这里我们们首先创建四个方向上的静态常量数组。

遍历所有格子的行和列,内部通过一个递归函数来查找,满足if条件就是查找到了相应的单词,返回true,否则返回false。

dfs递归函数是如何去做的呢?

先介绍一下参数列表:i是行,j是列,k是word的第k个字母,board就是棋盘上的字母,word就是需要我们查找的字母。

进入dfs后先找到第一个成功的字母,第一个不成功匹配的话直接就返回false了。直到k是word的最后一个字母时,经过第一个if的比对成功,就该返回true了。每访问一个结点的话就把它标记为访问过(也就是将其置为0的操作),避免节点走了回头路。

再通过一个for循环不断变化x,y的值相当于到达一个节点之后在四个方向上移动它去比较。if判断x,y的值一定是在合法的区间内,当前字母找到之后再让k+1去寻找下一个节点。

当前节点没找到的话,以为我们已经将其置为0了,必须要恢复现场。

DFS 是尝试所有可能路径的:

  • 你从 A 出发走了一条路,发现走不通
  • 你必须退回来,把 A 恢复成原来的字符
  • 不然其他路径想经过 A 时,会发现 A 是 0,就误以为不能走了
java 复制代码
class Solution {
    private static final int[][] DIRS = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};

    public boolean exist(char[][] board, String word) {
        char[] w = word.toCharArray();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[i].length; j++) {
                if (dfs(i, j, 0, board, w)) {
                    return true; // 搜到了!
                }
            }
        }
        return false; // 没搜到
    }

    private boolean dfs(int i, int j, int k, char[][] board, char[] word) {
        if (board[i][j] != word[k]) { // 匹配失败
            return false;
        }
        if (k == word.length - 1) { // 匹配成功!
            return true;
        }
        board[i][j] = 0; // 标记访问过
        for (int[] d : DIRS) {
            int x = i + d[0];
            int y = j + d[1]; // 相邻格子
            if (0 <= x && x < board.length && 0 <= y && y < board[x].length && dfs(x, y, k + 1, board, word)) {
                return true; // 搜到了!
            }
        }
        board[i][j] = word[k]; // 恢复现场
        return false; // 没搜到
    }
}

优化点:假设我们要找的word里面有两个字母C,但是board里面只有一个C,那么我们就不需要再遍历了,可以直接返回false.

并且

如果 word=abcd 但 board 中的 a 很多,d 很少(比如只有一个),那么从 d 开始搜索,能更快地找到答案。(即使我们肉眼去找,这种方法也是更快的)

设 word 的第一个字母在 board 中出现了 x 次,word 的最后一个字母在 board 中出现了 y 次。

如果 y<x,我们可以把 word 反转,相当于从 word 的最后一个字母开始搜索,这样更容易在一开始就满足 boardij != wordk,不会往下递归,递归的总次数更少。

优化后的代码如下:

java 复制代码
class Solution {
    private static final int[][] DIRS = {{0,-1},{0,1},{-1,0},{1,0}};
    public boolean exist(char[][] board, String word) {
        int[] cnt = new int[128];
        for(char[] row : board){
            for(char c : row){
                cnt[c] ++;
            }
        }
        char[] w = word.toCharArray();
        int[] wordCnt = new int[128];
       //优化点一 判断个数
        for(char c : w){
            if(++wordCnt[c] > cnt[c]){
                return false;
            }
        }
        //优化点二 看word开头字母出现的次数多还是结尾字母,结尾多直接反转word
        if(cnt[w[w.length-1]] < cnt[0]){
            w = new StringBuilder(word).reverse().toString().toCharArray();
        }
        for(int i =0;i < board.length;i++){
            for(int j = 0;j < board[i].length; j++){
                if(dfs(i,j,0,board,w)){
                    return true;
                }
            }
        }
        return false;
        
    }
    private boolean dfs(int i, int j, int k, char[][] board, char[] word){
        if(board[i][j] != word[k]){
            return false;
        }
        if(k == word.length -1){
            return true;
        }
        board[i][j] = 0;
        for(int[] d :DIRS){
            int x = i + d[0];
            int y = j + d[1];
            if(0<= x && x < board.length && 0<= y && y < board[x].length && dfs(x,y,k+1,board,word)){
                   return true;
            }
        }
         board[i][j] = word[k];
         return false;
    }
}

参考:

作者:灵茶山艾府

链接:https://leetcode.cn/problems/word-search/solutions/2927294/liang-ge-you-hua-rang-dai-ma-ji-bai-jie-g3mmm/

相关推荐
小欣加油13 小时前
leetcode56 合并区间
c++·算法·leetcode·职场和发展
lqqjuly13 小时前
前沿算法深度解析(二)
人工智能·算法·机器学习
徐小夕15 小时前
万字长文!千万级文档 RAG 知识库系统落地实践
前端·算法·github
akunkuntaimei15 小时前
2026年高考数学各省真题及答案(完整版)
算法·高考
Hello:CodeWorld16 小时前
C 风格变参 vs C++ 变参模板:核心区别与选型指南
c语言·c++·算法
8Qi817 小时前
LeetCode 516:最长回文子序列
算法·leetcode·职场和发展·动态规划
youngerwang18 小时前
【从搬运工到协处理器:网卡芯片架构、算法、验证与边缘演进深度剖析】
网络·算法·架构·芯片
想要成为糕糕手18 小时前
前端必修课:JavaScript 数组与数据结构底层逻辑全解析
javascript·数据结构·面试
KaMeidebaby18 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
手写码匠19 小时前
从零实现 Prompt 工程引擎:结构化提示、自动优化与多轮自省体系
人工智能·深度学习·算法·aigc