79. Word Search**

79. Word Search**

https://leetcode.com/problems/word-search/

闲扯: 这几天都在看<临高启明>, 没有坚持写题, 不是意志力的问题, 只怪小说太好看 🤣

题目描述

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

Given word = "ABCCED", return true.
Given word = "SEE", return true.
Given word = "ABCB", return false.

C++ 实现 1

DFS + Backtracing. 从 board 中的每个字符开始, 通过 DFS 寻找一个字符串和 word 相等. 这要保证寻找到的字符串每个字符和 word 中的每个字符依次相等. 由于 board 的字符访问过后不能再次访问了, 因此使用额外的 visited 数组记录哪些字符已经被访问了. 使用 k 来遍历 word 中的字符.

dfs 函数中, 有如下情况返回 false:

  • board 访问越界;
  • k 访问 word 越界;
  • board[i][j]: 当前访问的字符已经被访问过;
  • board[i][j]word[k] 不相等;

只有当 k 指向 word 的最后一个字符并且满足 word[k] == board[i][j] 时, 才返回 true.

另外 Backtracing 时需要将 visited[i][j] 重置为 false.

class Solution {
private:
    vector<vector<bool>> visited;
    bool dfs(vector<vector<char>> &board, int i, int j, const string &word, int k) {
        int m = board.size(), n = board[0].size(), ws = word.size();
        if (i < 0 || i >= m || j < 0 || j >= n || k >= ws || visited[i][j]) return false;
        if (k == ws - 1 && board[i][j] == word[k]) return true;
        if (board[i][j] != word[k]) return false;
        visited[i][j] = true;
        bool res = 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);
        visited[i][j] = false;
        return res;
    }
public:
    bool exist(vector<vector<char>>& board, string word) {
        if (board.empty() || board[0].empty()) return false;
        int m = board.size(), n = board[0].size();
        visited = vector<vector<bool>>(m, vector<bool>(n, false));
        for (int i = 0; i < m; ++ i) {
            for (int j = 0; j < n; ++ j) {
                bool res = dfs(board, i, j, word, 0);
                if (res) return true;
            }
        }
        return false;
    }
};

C++ 实现 2

C++ 实现 1 快很多.

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        bool res = false;
        int m = board.size(), n = board[0].size();
        seen = vector<vector<bool>>(m, vector<bool>(n, false));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                if (board[i][j] == word[0]) {
                    dfs(board, word, 0, res, m, n, i, j);
                    if (res)
                        break;
                }
            }
        }
        return res;
    }
private:
    vector<vector<bool>> seen;
    void dfs(vector<vector<char>> &board, string &word, int start,
            bool &res,
            int m, int n,
            int i, int j) {
        if (i < 0 || i >= m ||
            j < 0 || j >= n ||
            seen[i][j] ||
            board[i][j] != word[start])
            return;
        
        // 这行代码可以让下面的 4 个 dfs 有可能提前结束.
        // 比如第 2 个 dfs 已经得到 res 为 true,
        // 那么第 3 和 4 个 dfs 能提前 return.
        if (res)
            return;

        if (start == word.size() - 1) {
            res = true;
            return;
        }

        seen[i][j] = true;
        dfs(board, word, start + 1, res, m, n, i + 1, j);
        dfs(board, word, start + 1, res, m, n, i - 1, j);
        dfs(board, word, start + 1, res, m, n, i, j - 1);
        dfs(board, word, start + 1, res, m, n, i, j + 1);
        seen[i][j] = false;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值