[leetcode] 212. Word Search II 解题报告

题目链接: https://leetcode.com/problems/word-search-ii/

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must 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 in a word.

For example,
Given words = ["oath","pea","eat","rain"] and board =

[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]
Return  ["eat","oath"] .

Note:
You may assume that all inputs are consist of lowercase letters a-z.


思路: 一种比较直观的方法是每个单词进行一次DFS搜索, 但是这样速度比较慢, 其时间复杂度最坏会达到O(m^2 * n^2 *k), 即每个单词都会从地图的每一个元素开始搜索, 如果单词足够长且每次都搜索完整个地图, 那么时间复杂度就是最坏了. 这种方法肯定是不能完成大量数据的. 这是我最初的想法, 代码如下:

class Solution {
public:
    bool DFS(vector<vector<char>>& board, string str, int index, int x, int y, vector<vector<bool>> flag)
    {
        if(index >= str.size()){ result.push_back(str); return true;}
        if(x < 0 || x >= board.size() || y <0 || y >= board[0].size() || flag[x][y] == true)
            return false;
        flag[x][y] = true;
        if(board[x][y] == str[index])
        {
            if(DFS(board, str, index+1, x+1, y, flag) == true) return true;
            if(DFS(board, str, index+1, x-1, y, flag) == true) return true;
            if(DFS(board, str, index+1, x, y+1, flag) == true) return true;
            if(DFS(board, str, index+1, x, y-1, flag) == true) return true;
        }
        return false;
    }
    
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        if(board.size()==0 || words.size()==0) return {};
        int m = board.size(), n = board[0].size();
        
        for(auto str: words)
        {
            bool f = false;
            for(int i =0; i< m && f==false; i++)
                for(int j =0; j < n && f==false; j++)
                    if(board[i][j] == str[0])
                    {
                        vector<vector<bool>> flag(m, vector<bool>(n, false));
                        if(DFS(board, str, 0, i, j, flag) == true)
                            f = true;
                    }
        }
        return result;
    }
private:
    vector<string> result;
};


更好的方法是利用字典树Trie来做, 就是将要搜索的单词先添加到字典树中, 然后从地图board的每一个元素搜索, 如果往上下左右搜索的时候其元素可以在字典树中找到, 那么就继续搜索下去, 并且如果搜索到某个结点的时候发现到这个结点构成了一个单词, 那么就将单词添加到结果集合中. 如果在字典树中无法找到这个元素, 那么就结束当前分支的搜索.

代码如下:

class Solution {
public:
    struct Trie
    {
        vector<Trie*> child;
        string str;
        Trie(): child(vector<Trie*>(26, NULL)), str(""){}
    };
    
    void addWord(vector<string>& words)
    {
        for(auto str: words){
            Trie* tem = root;
            for(auto ch: str){
                if(tem->child[ch - 'a'] == NULL) 
                    tem->child[ch - 'a'] = new Trie();
                tem = tem->child[ch - 'a'];
            }
            tem->str = str;
        }
    }
    
    void DFS(vector<vector<char>>& board, int x, int y, Trie* node)
    {
        char ch = board[x][y];
        if(node->child[ch-'a'] == NULL || board[x][y] =='$') return;
        if(node->child[ch-'a']->str.size() > 0)
        {
            result.push_back(node->child[ch-'a']->str);
            node->child[ch-'a']->str = "";
        }
        board[x][y] = '$';
        if(y+1 < board[0].size()) DFS(board, x, y+1, node->child[ch - 'a']);
        if(y-1 >= 0) DFS(board, x, y-1, node->child[ch - 'a']);
        if(x+1 < board.size()) DFS(board, x+1, y, node->child[ch - 'a']);
        if(x-1 >=0) DFS(board, x-1, y, node->child[ch - 'a']);
        board[x][y] = ch;
    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        if(board.size()==0 || words.size()==0) return {};
        int m = board.size(), n = board[0].size();
        root = new Trie();
        addWord(words);
        for(int i = 0; i< m; i++)
            for(int j =0; j< n; j++)
                DFS(board, i, j, root);
        return result;
    }
    
private:
    vector<string> result;
    Trie* root;
};
参考: https://leetcode.com/discuss/77851/java-15ms-easiest-solution-100-00%25

你可能感兴趣的:(LeetCode,DFS,trie)