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

相关推荐
未来之窗软件服务16 小时前
幽冥大陆(二)RDIFSDK 接口文档:布草洗涤厂高效运营的技术桥梁C#—东方仙盟
开发语言·c#·rdif·仙盟创梦ide·东方仙盟
1uther16 小时前
Unity核心概念⑨:Screen
开发语言·游戏·unity·c#·游戏引擎
阿幸软件杂货间17 小时前
Office转PDF转换器v1.0.py
开发语言·pdf·c#
sali-tec18 小时前
C# 基于halcon的视觉工作流-章34-环状测量
开发语言·图像处理·算法·计算机视觉·c#
Tiger_shl18 小时前
【层面一】C#语言基础和核心语法-02(反射/委托/事件)
开发语言·c#
mudtools1 天前
.NET驾驭Word之力:COM组件二次开发全攻略之连接Word与创建你的第一个自动化文档
后端·c#
王维志1 天前
LiteDB详解
数据库·后端·mongodb·sqlite·c#·json·database
程序猿多布1 天前
XLua教程之热补丁技术
unity·c#·lua·xlua
咕白m6251 天前
C# Excel 读取入门教程:免费实现方法
c#·.net
相与还1 天前
godot+c#使用godot-sqlite连接数据库
数据库·c#·godot