leetcode 79. Word Search 、212. Word Search II

 

https://www.cnblogs.com/grandyang/p/4332313.html

在一个矩阵中能不能找到string的一条路径 

 

这个题使用的是dfs。但这个题与number of islands有点不同,那个题中visited过的就不用再扫了,但是这个需要进行回溯回来。

所以使用了visited[i][j] = false;

本质区别还是那个题是找一片区域,这个题更像是找一条路径。

 

错误一:如果board不引用,会报超内存

错误二:

这个写法和正确写法基本相同,但错误写法需要每次都去遍历flag1、flag2、flag3、flag4,正确写法中,如果flag1为真,就不用再去遍历flag2、3、4,这样就节省了许多时间。

所以这个写法报的错误是在有一个比较大的case超时。

https://blog.csdn.net/CV2017/article/details/82659742

或运算符,左右两边通常为关系或相等表达式,第一个操作数将完全运算,仅当第一个操作数的计算结果为 false 时计算第二个操作数,当第一个操作数的计算结果为 true 时,不用计算第二个操作数和这之后的操作数,直接运行后面的代码了

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();
        vector<vector<bool> > visited(m,vector<bool>(n));
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                int index = 0;
                if(exit(board,word,i,j,index,visited))
                    return true;
            }
        }
        return false;
    }

    bool exit(vector<vector<char>>& board,string word,int i,int j,int index,vector<vector<bool>>& visited){
        if(index == word.size())
            return true;
        if(i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || visited[i][j] == true || board[i][j] != word[index])
            return false;
        visited[i][j] = true;
        bool flag1 = exit(board,word,i - 1,j,index+1,visited);
        bool flag2 = exit(board,word,i + 1,j,index+1,visited);
        bool flag3 = exit(board,word,i,j - 1,index+1,visited);
        bool flag4 = exit(board,word,i,j + 1,index+1,visited);
        visited[i][j] = false;
        return flag1 || flag2 || flag3 || flag4;

    }
};

 

正确写法:

如果第一个字符不相同,就继续遍历,这个操作可以减少搜索的个数

vector<vector<bool>> visited(m,vector<bool>(n,false));不要写在for循环里面,其实每次递归都是将置为true的又置为了false的。

class Solution {
public:
    bool exist(vector<vector<char>>& board, string word) {
        int m = board.size();
        int n = board[0].size();
        vector<vector<bool> > visited(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])
                    continue;
                int index = 0;
                if(exit(board,word,i,j,index,visited))
                    return true;
            }
        }
        return false;
    }

    bool exit(vector<vector<char>>& board,string word,int i,int j,int index,vector<vector<bool>>& visited){
        if(index == word.size())
            return true;
        if(i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || visited[i][j] == true || board[i][j] != word[index])
            return false;
        visited[i][j] = true;
        bool res = exit(board,word,i - 1,j,index+1,visited) || exit(board,word,i + 1,j,index+1,visited) || exit(board,word,i,j - 1,index+1,visited) || exit(board,word,i,j + 1,index+1,visited);
        visited[i][j] = false;
        return res;

    }
};

 

 

212. Word Search II 

https://www.cnblogs.com/grandyang/p/4516013.html

这个题是trie树与dfs相结合的题目,将所有需要搜索的词存入trie树当中,然后在二维数组中dfs搜索。

这个题的trie树的定义和leetcode 208. Implement Trie (Prefix Tree) 、211. Add and Search Word - Data structure design的不太一样,208、211定义了一个isWord

用来表示是否是词的结尾。这个题定义的则是一个string,并且这个string存储的就是整个单词,这样既可以用来表示结尾,又可以获得搜索的整个词。这样做主要是由于

这个题目本身要求返回搜索成功的词。

这个题在搜索到词后,还需要clear掉str,因为题目要求同一个词只返回一个,例子如下:

Input:
[["a","a"]]
["a"]
Output:
["a","a"]
Expected:
["a"]

class Solution {
public:
    struct TrieNode{
        TrieNode* child[26];
        string str;
        TrieNode():str(""){
            for(int i = 0;i < 26;i++)
                child[i] = NULL;
        }
    };
    struct Trie{
        TrieNode* root;
        Trie():root(new TrieNode()){
        }
        void insert(string s){
            TrieNode* p = root;
            for(char tmp : s){
                int i = tmp - 'a';
                if(!p->child[i])
                    p->child[i] = new TrieNode();
                p = p->child[i];
            }
            p->str = s;
            return;
        }
    };
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        vector<string> res;
        if(board.empty() || board[0].empty() || words.empty())
            return res;
        int m = board.size(),n = board[0].size();
        Trie T;
        for(string word : words)
            T.insert(word);
        vector<vector<bool>> visited(m,vector<bool>(n,false));
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                if(T.root->child[board[i][j] - 'a'])
                    findWords(board,T.root->child[board[i][j] - 'a'],visited,i,j,res);
            }
        }
        return res;
    }
    void findWords(vector<vector<char>>& board,TrieNode* p,vector<vector<bool>>& visited,int i,int j,vector<string>& res){
        if(!p->str.empty()){
            res.push_back(p->str);
            p->str.clear();
        }
        visited[i][j] = true;
        for(auto dir : dirs){
            int x = i + dir[0];
            int y = j + dir[1];
            if(x < 0 || x >= board.size() || y < 0 || y >= board[0].size() || visited[x][y] == true || p->child[board[x][y] - 'a'] == NULL)
                continue;
            findWords(board, p->child[board[x][y] - 'a'],visited, x, y, res);
        }
        visited[i][j] = false;
        return;
    }
private:
    vector<vector<int>> dirs{{-1,0},{1,0},{0,-1},{0,1}};
};

 

posted @ 2019-03-06 16:56  有梦就要去实现他  阅读(267)  评论(0编辑  收藏  举报