LintCode 123 · Word Search (DFS字符处理经典题!)

123 · Word Search

Algorithms

Medium

Description

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

The string 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.

The dimension of the letter matrix does not exceed 100, and the length of the string does not exceed 100.

Example

Example 1:

Input:

board = "ABCE","SFCS","ADEE"

word = "ABCCED"

Output:

true

Explanation:

A B C E S F C S A D E E

(0,0)->(0,1)->(0,2)->(1,2)->(2,2)->(2,1)

Example 1:

Input:

board = "z"

word = "z"

Output:

true

Explanation:

z

(0,0)

解法1:DFS+hashset。

很多小地方需要注意,特别是visited\[\]\[\]数组什么时候clear掉。

cpp 复制代码
class Solution {
public:
    /**
     * @param board: A list of lists of character
     * @param word: A string
     * @return: A boolean
     */
    bool exist(vector<vector<char>> &board, string &word) {
        int m = board.size();
        if (m == 0) return word.empty();
        int n = board[0].size();
        string sol = "";
        for (int i = 0; i < word.size(); i++) {
            string tmpStr = word.substr(0, i + 1);
            s.insert(tmpStr);
        }
        vector<vector<bool>> visited;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                sol.clear(); //这里每次都要clear!不然后面的操作就append到s上面!
                visited.resize(m, vector<bool>(n, false));
                sol += board[i][j];
                if (check(board, word, sol, visited, i, j)) return true;
            }
        }
        return false;
    }
private:
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    set<string> s;
    bool check(vector<vector<char>> &board, string &word, string sol, vector<vector<bool>> &visited, int x, int y) {
        if (s.find(sol) == s.end()) return false;
        if (sol == word) {
            return true;
        }
        if (sol.size() >= word.size()) return false;
        visited[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int newX = x + dx[i];
            int newY = y + dy[i];
            if (newX >= 0 && newX < board.size() && newY >= 0 && newY < board[0].size() && !visited[newX][newY]) {
                sol += board[newX][newY];
                if (check(board, word, sol, visited, newX, newY)) return true;
                else sol.pop_back();  //这一行重要!因为sol还要被for循环的其它i用到!
            }
        }
        visited[x][y] = false; //这一行重要,只有当dfs能够一直往下进行,visited[][]才不用动,否则如果dfs中途退出,visited[][]要clear。不然就跟后面操作冲突!
        return false; //这里别忘了,不然默认可能会返回true!!!
    }
};

二刷:不需要set。每次比较当前位置的字符就可以了。

cpp 复制代码
class Solution {
public:
    /**
     * @param board: A list of lists of character
     * @param word: A string
     * @return: A boolean
     */
    bool exist(vector<vector<char>> &board, string &word) {
        int m = board.size();
        if (m == 0) return word.empty();
        int n = board[0].size();
        string sol = "";
        vector<vector<bool>> visited;
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                sol.clear();
                visited.resize(m, vector<bool>(n, false));
                sol += board[i][j];
                if (check(board, word, sol, 0, visited, i, j)) return true;
            }
        }
        return false;
    }
private:
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    bool check(vector<vector<char>> &board, string &word, string sol, int pos, vector<vector<bool>> &visited, int x, int y) {
        if (sol[pos] != word[pos]) return false;
        if (sol == word) {
            return true;
        }
        //if (sol.size() >= word.size()) return false; //这一行不需要!如果不匹配早就返回了,匹配上面也会返回true。
        visited[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int newX = x + dx[i];
            int newY = y + dy[i];
            if (newX >= 0 && newX < board.size() && newY >= 0 && newY < board[0].size() && !visited[newX][newY]) {
                sol += board[newX][newY];
                if (check(board, word, sol, pos + 1, visited, newX, newY)) return true;
                else sol.pop_back();  //这一行重要!因为sol还要被for循环的其它i用到!
            }
        }
        visited[x][y] = false; //这一行重要,只有当dfs能够一直往下进行,visited[][]才不用动,否则如果dfs中途退出,visited[][]要clear。不然就跟后面操作冲突!
        return false;
    }
};

三刷: DFS+Trie

TBD

四刷:BFS

TBD

相关推荐
哪 吒37 分钟前
华为OD机试 - 云服务安全策略最优选择 - 深度优先搜索DFS(Java 新系统 200分)
java·华为od·深度优先
海盗12342 小时前
微软技术周报 2026-08-31~09-07:GPT-6 Astra 登陆 Foundry、M365 全球认证故障复盘、C# 15 封闭层级
gpt·microsoft·c#
reasonsummer3 小时前
【办公类-115-01】20260906育儿知识(家园小报)批量制作(2026年9月-2027年6月)
开发语言·数据库·c#
鹿角片ljp4 小时前
LeetCode 22:括号生成|回溯dfs、剪枝与 char[] 覆盖代替撤销
算法·深度优先
软件黑马王子4 小时前
13.缓存池优化:对象上限配置
开发语言·前端框架·c#
唐青枫4 小时前
C#.NET StructureMap 从依赖注入到项目实战
c#·.net
fujisheng6614 小时前
FUI 编译期装配实践:从反射注册到 Source Generator
c#·unity3d
智码看视界4 小时前
.NET 10 推理大模型TensorSharp 3.3.0 部署实测:纯.NET推理引擎反超llama.cpp 1.5倍,DFlash2提速62%
c#·.net·llama.cpp·.net 10·tensorsharp·本地大模型推理·开源推理引擎
格林威5 小时前
C# 图像异步落盘存储:基于Channel 配合 ArrayPool 实现异步落盘
开发语言·人工智能·数码相机·机器学习·计算机视觉·c#·视觉检测
软件黑马王子5 小时前
11.缓存池优化:窗口布局
开发语言·前端框架·c#