zoukankan      html  css  js  c++  java
  • 79. Word Search

    Problem statement:

    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.

    For example,
    Given board =

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

    word = "ABCCED", -> returns true,
    word = "SEE", -> returns true,
    word = "ABCB", -> returns false.

    Solution:

    In this problem, we are given a two dimension board, it is naturally that we can use BFS and DFS, I am familiar with BFS,  so I use BFS first to solve it. The code is as following:

    class Solution {
    public:
        bool exist(vector<vector<char>>& board, string word) {
            if(word.empty()){
                return false;
            }
            vector<pair<int, int>> start_points;
            for(int i = 0; i < board.size(); i++){
                for(int j = 0; j < board[i].size(); j++){
                    if(board[i][j] == word[0]){
                        start_points.push_back({i, j});
                    }
                }
            }
            
            for(auto point : start_points){
                if(bfs_search(board, point, word)){
                    return true;
                }
            }
            
            return false;
        }
    private:
        bool bfs_search(vector<vector<char>>& board, pair<int, int> start, string word){
            int idx = 0;
            int row = board.size();
            int col = board[0].size();
            
            vector<pair<int, int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
            vector<vector<int>> visited(row, vector<int>(col, 0));
            visited[start.first][start.second] = 1;
            queue<pair<int, int>> que;
            que.push(start);
            
            while(!que.empty()){
                idx++;
                int size = que.size();
                while(size > 0){
                    pair<int, int> cur = que.front();
                    que.pop();
                    for(auto dir : dirs){
                        int x = cur.first + dir.first;
                        int y = cur.second + dir.second;
                        if(x >= 0 && x < row && y >= 0 && y < col 
                            && visited[x][y] == 0 // never visited
                            && idx < word.size() && board[x][y] == word[idx]){
                            que.push({x, y});
                            visited[x][y] = 1;
                        }
                    } 
                    size--;
                }
            }
            return idx == word.size();
        } 
    };

    This is a pretty easy understand BFS code, but it can not pass OJ since there is a test case: 

    ["ABCE","SFES","ADEE"]

    "ABCESEEEFS"

    [A B C E]

    [S F E S]

    [A D E E]

    When we do BFS search, the "E" in [0, 3], [1, 2] will marked visited in the same time. however if we marked the "E" in [1, 2], BFS will return false. This is not we want. So DFS is the best solution to solve this problem.

    class Solution {
    public:
        bool exist(vector<vector<char>>& board, string word) {
            if(word.empty()){
                return false;
            }
            int row = board.size();
            int col = board[0].size();
            vector<pair<int, int>> start_points;
            for(int i = 0; i < board.size(); i++){
                for(int j = 0; j < board[i].size(); j++){
                    if(board[i][j] == word[0]){
                        // for each char in board which is equal the first char in word
                        // initialize a new dfs search
                        vector<vector<int>> visited(row, vector<int>(col, 0));
                        // current position is visited
                        visited[i][j] = 1;
                        // dfs search
                        if(word_search_dfs(board, visited, {i, j}, word, row, col, 1)){
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    private:
    
        bool word_search_dfs(vector<vector<char>>& board, 
                            vector<vector<int>>& visited, 
                            pair<int, int> start, string word, int row, int col, int idx){
            // if the size is equal to word size
            // return true because we already find a path
            if(idx == word.size()){
                return true;
            }
            vector<pair<int, int>> dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
            for(auto dir : dirs){
                int x = start.first + dir.first;
                int y = start.second + dir.second;
                if(x >= 0 && x < row && y >= 0 && y < col && visited[x][y] == 0 && board[x][y] == word[idx]){
                    visited[x][y] = 1;
                    if(word_search_dfs(board, visited, {x, y}, word, row, col, idx + 1)){
                        return true;
                    }
                    visited[x][y] = 0;
                }
            }
            return false;
        }
    };
  • 相关阅读:
    RDIFramework.NET开发实例━表约束条件权限的使用-WinForm
    RDIFramework.NET V2.8版本 ━ 开发实例之产品管理(WinForm)
    RDIFramework.NET ━ Web中打印的各种方案参考-欢迎补充
    RDIFramework.NET 框架兼容各种数据库类型事务使用范例参考
    【干货】再上数据分页控件 ━ 更加灵活,更加实用-提供源码
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增岗位管理-Web部分
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本━新增岗位管理-WinForm部分
    RDIFramework.NET ━ .NET快速信息化系统开发框架 V2.8 版本发布
    Javascript中的apply与call详解
    Javascript定义类(class)的三种方法
  • 原文地址:https://www.cnblogs.com/wdw828/p/6839083.html
Copyright © 2011-2022 走看看