212 单词搜索II

思路:

先将单词插入到前缀树中,然后再DFS一步步去判断下一个要遍历的字符是否存在前缀树中,若存在,则加入中间变量中,若当前遍历的字符序列在字典树中组成一个单词,则加入ans中

不存在,则停止该方向的搜索,因为前缀不存在,则后面DFS生成的单词均以此为前缀,均不存在

在DFS时使用一个set来保存存在于前缀树中的单词,因为遍历时可能会有重复的单词加入,注意DFS时对于vis数组和中间变量的重置。

最后将自动排序好的set转为vector作为ans返回即可。

class Trie
{
public:
    bool is_end;
    Trie *next[26]; // 单词在a - z之间
    Trie()
    {
        is_end = false;
        for(int i = 0; i < 26; ++i) next[i] = nullptr;
    }

    void insert(const string& word)
    {
        Trie *t = this;
        for(auto i : word)
        {
            if(t->next[i - 'a'] == nullptr) t->next[i - 'a'] = new Trie();
            t = t->next[i - 'a'];
        }
        t->is_end = true;
    }
};

class Solution {
    Trie *root;
    int row, col;
    int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
    set<string> aws; // 暂存遍历时的存在的单词,可能会有重复元素,去重用set
    string temp; // 用来存储遍历时生成的中间字符串
    vector<vector<bool>> vis; // 标记是否访问过
public:
    Solution(){root = new Trie();}

    void DFS(int i, int j, const vector<vector<char>>& board, const Trie *t)
    {
        char c = board[i][j];
        printf("%c", c);
        temp.push_back(c);
        if(t->next[c - 'a'] == nullptr)
        {
            temp.pop_back();
            // 每次生成字符串时不能访问这次已经访问过的点,但是下一次开始时能访问与上一次重复的点,要重置vis
            vis[i][j] = false;
            return;
        }
        vis[i][j] = true;
        if(t->next[c - 'a']->is_end == true) aws.insert(temp); // 组成前缀树中的一个单词
        for(int k = 0; k < 4; ++k)
        {
            int I = dx[k] + i, J = dy[k] + j;
            if(I >= 0 && I < row && J >= 0 && J < col && vis[I][J] == false)
                DFS(I, J, board, t->next[c - 'a']);
        }
        // 运行到这里重置vis和temp
        vis[i][j] = false;
        temp.pop_back();
    }

    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        for(auto s : words) root->insert(s); // 先将单词插入到前缀树中
        row = board.size(), col = board[0].size();
        vis.resize(row);
        for(int i = 0; i < row; ++i)
        {
            vis[i].resize(col);
            fill(vis[i].begin(), vis[i].end(), false);
        }
        for(int i = 0; i < row; ++i) // 对整个图DFS
            for(int j = 0; j < col; ++j)
                DFS(i, j, board, root);
        vector<string> ans(aws.begin(), aws.end()); // set转换为vector
        return ans;
    }
};

你可能感兴趣的:(Leetcode)