LongDz 的数字文墨提案

79. 单词搜索

4 min

题目

单词搜索 中等

解法:DFS回溯

思路

深度优先搜索(DFS)结合回溯法,通过原地修改网格标记访问状态来避免重复使用单元格。

该方法正确性基于穷举所有可能路径:从每个单元格出发,递归探索四个方向的所有可能路径。当路径上的字符与单词完全匹配且长度一致时即找到解。标记已访问单元格确保不重复使用,回溯时恢复状态保证不同搜索路径互不干扰,从而不会遗漏任何潜在解。

  • Step 1: 遍历网格中每个单元格作为搜索起点
  • Step 2: 在DFS中检查边界和字符匹配,若匹配则继续递归
  • Step 3: 临时修改当前单元格字符为特殊标记’#‘防止重复访问
  • Step 4: 向上下左右四个方向递归搜索下一个字符
  • Step 5: 回溯时恢复单元格原始字符,尝试其他路径

复杂度

  • 时间复杂度: O(m×n×4k)O(m \times n \times 4^k),其中m、n为网格维度,k为单词长度。最坏情况下需遍历所有起点并探索四个方向的所有可能路径。
  • 空间复杂度: O(k)O(k),递归调用栈的最大深度为单词长度,用于保存搜索路径状态。

代码

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (dfs(board, i, j, word, 0)) {
                    return true;
                }
            }
        }

        return false;
    }

    bool dfs(vector<vector<char>>& board, int i, int j, const string& word, int k) {
        int m = board.size();
        int n = board[0].size();

        // 越界或字母不匹配
        if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
            return false;
        }
class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();

        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (dfs(board, i, j, word, 0)) {
                    return true;
                }
            }
        }

        return false;
    }

    bool dfs(vector<vector<char>>& board, int i, int j, const string& word, int k) {
        int m = board.size();
        int n = board[0].size();

        // 越界或字母不匹配
        if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != word[k]) {
            return false;
        }

        // 找到最后一个字符
        if (k == word.size() - 1) {
            return true;
        }

        // 标记已访问(防止走回头路)
        char temp = board[i][j];
        board[i][j] = '#';

        // 尝试四个方向
        bool found = dfs(board, i + 1, j, word, k + 1) ||
                     dfs(board, i - 1, j, word, k + 1) ||
                     dfs(board, i, j + 1, word, k + 1) ||
                     dfs(board, i, j - 1, word, k + 1);

        // 回溯
        board[i][j] = temp;

        return found;
    }
};