212. Word Search II

// improvement:
// 1) convert unordered_map to 26 bitmap (done)
// 2) for each step in dfs, we don't have search the word from beginning in trie,
//    we can actually search from previous node. should be faster.
class Node {
public:
    char v;
    bool isWord;
    vector<Node*> m;
    //unordered_map<char, Node*> m;
    Node(char _v, bool _isWord = false) {
        v = _v;
        isWord = _isWord;
        m = vector<Node*>(26, nullptr);
    }
};
class Trie {
public:  
    Node *root = new Node(0);
    void build(vector<string>& words) {
        for (auto& w : words)
            add(w);
    }
    void add(const string& w) {
        Node *cur = root;
        for (auto c : w) {
            if (cur->m[c-'a'] == nullptr)
                cur->m[c-'a'] = new Node(c);
            cur = cur->m[c-'a'];
        }
        cur->isWord = true;
    }
    int search(string &w) {
        Node *cur = root;
        for (auto c : w) {
            if (cur->m[c-'a'] == nullptr)
                return 0;
            cur = cur->m[c-'a'];
        }
        return cur->isWord ? 2 : 1;
    }
};
class Solution {
public:
    int m, n;
    unordered_set<string> res;
    string path;
    Trie trie;
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
        m = board.size(); if (m == 0)   return vector<string>();
        n = board[0].size();  if (n == 0)   return vector<string>();
        trie.build(words);
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++) {
                path.push_back(board[i][j]);
                dfs(board, i, j);
                path.pop_back();
            }
        return vector<string>(res.begin(), res.end());
    }
    void dfs(vector<vector<char>>& board, int i, int j) {
        static int dirs[] = { -1, 0, 1, 0, -1};
        
        int state = trie.search(path);
        if (state == 2)
            res.insert(path);
        else if (state == 0)
            return;
        
        char saved = board[i][j];
        board[i][j] = ' ';
        for (int k = 0; k < 4; k++) {
            int ni = i + dirs[k];
            int nj = j + dirs[k+1];
            if (ni < 0 || ni >= m || nj < 0 || nj >= n || board[ni][nj] == ' ')
                continue;
            
            path.push_back(board[ni][nj]);
            dfs(board, ni, nj);
            path.pop_back();
        }
        board[i][j] = saved;
    }
};
原文地址:https://www.cnblogs.com/JTechRoad/p/10058821.html