Skip to content

Latest commit

 

History

History
90 lines (70 loc) · 4.34 KB

File metadata and controls

90 lines (70 loc) · 4.34 KB

Screen Shot Screen Shot

// Trie node = one prefix state in the dictionary.
struct TrieNode {
    // Map from next character -> pointer to the next TrieNode.
    // Example: children['a'] points to the node that represents adding 'a' to current prefix.
    unordered_map<char, TrieNode*> children;

    // If this node ends a word, store the full word here; otherwise "".
    // We store the full word so we can output it immediately when we reach this node in DFS.
    string endword;
};

class Solution {
public:
    vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {

        TrieNode* root = new TrieNode();                 // Root of Trie: represents empty prefix "".

        // ---------- Build Trie from all words ----------
        for (auto word : words) {                        // Insert each word into the Trie.
            TrieNode* node = root;                       // Start from root for each word.
            for (char letter : word) {                   // Walk characters in this word.
                // node->children[letter] returns a TrieNode* (default nullptr if key not present).
                if (!node->children[letter])             // If this edge doesn't exist yet...
                    node->children[letter] = new TrieNode(); // Create the next Trie node.
                node = node->children[letter];           // Move "node" forward along the Trie path.
            }
            node->endword = word;                        // Mark: this Trie path completes a word.
        }

        int m = board.size();                            // Number of rows in board.
        int n = board[0].size();                         // Number of cols in board.
        vector<string> res;                              // Final answers (found words).

        // backtrack(i, j, node) means:
        // - We are standing on board cell (i, j)
        // - "node" is the Trie node for the prefix matched BEFORE using board[i][j]
        // - We will try to consume board[i][j] as the next letter in the Trie.
        function<void(int, int, TrieNode*)> backtrack =
            [&](int i, int j, TrieNode* node) {

            char letter = board[i][j];                   // Current board character we want to match.

            // Find whether this Trie prefix can go to "letter".
            auto it = node->children.find(letter);       // it points to (key=letter, value=nextNode).
            if (it == node->children.end()) return;      // No such edge => no word can match => prune.

            TrieNode* curr = it->second;                 // Move Trie state forward: prefix + letter.

            // If curr ends a word, we found one word on the board path.
            if (!curr->endword.empty()) {                // endword != "" means "this prefix is a full word"
                res.push_back(curr->endword);            // Add it to results.
                curr->endword.clear();                   // Clear to avoid duplicates (same word found again).
            }

            board[i][j] = '.';                           // Mark this cell as visited (can't reuse in path).

            pair<int, int> dirs[] = {                    // 4-direction moves.
                {-1, 0}, { 1, 0}, { 0,-1}, { 0, 1}
            };

            for (auto [di, dj] : dirs) {                 // Try each direction from current cell.
                int x = i + di;                          // Next row.
                int y = j + dj;                          // Next col.

                // Check boundaries and also ensure we don't step into a visited cell '.'.
                if (x >= 0 && y >= 0 && x < m && y < n && board[x][y] != '.') {
                    backtrack(x, y, curr);               // DFS to neighbor with updated Trie state.
                }
            }

            board[i][j] = letter;                        // Restore original letter (undo visited mark).
        };

        // ---------- Start DFS from every cell ----------
        for (int i = 0; i < m; i++) {                    // For each row...
            for (int j = 0; j < n; j++) {                // For each col...
                backtrack(i, j, root);                   // Try to start matching from this cell.
            }
        }

        return res;                                      // Return all found words (unique).
    }
};