LeetCode in Net

211. Design Add and Search Words Data Structure

Medium

Design a data structure that supports adding new words and finding if a string matches any previously added string.

Implement the WordDictionary class:

Example:

Input

["WordDictionary","addWord","addWord","addWord","search","search","search","search"] [[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]]

Output

[null,null,null,null,false,true,true,true]

Explanation

WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // return False
wordDictionary.search("bad"); // return True
wordDictionary.search(".ad"); // return True
wordDictionary.search("b.."); // return True 

Constraints:

Solution

public class WordDictionary {
    private class Node {
        public Node[] kids = new Node[26];
        public bool isTerminal;
    }

    private readonly Node[] root = new Node[26];

    public WordDictionary() {
        // empty constructor
    }

    public void AddWord(string word) {
        int n = word.Length;
        if (root[n] == null) {
            root[n] = new Node();
        }
        Node node = root[n];
        for (int i = 0; i < n; i++) {
            int c = word[i] - 'a';
            Node kid = node.kids[c];
            if (kid == null) {
                kid = new Node();
                node.kids[c] = kid;
            }
            node = kid;
        }
        node.isTerminal = true;
    }

    public bool Search(string word) {
        Node node = root[word.Length];
        return node != null && Dfs(0, node, word);
    }

    private bool Dfs(int i, Node node, string word) {
        int len = word.Length;
        if (i == len) {
            return false;
        }
        char c = word[i];
        if (c == '.') {
            foreach (Node kid in node.kids) {
                if (kid == null) {
                    continue;
                }
                if ((i == len - 1 && kid.isTerminal) || Dfs(i + 1, kid, word)) {
                    return true;
                }
            }
            return false;
        }
        Node next = node.kids[c - 'a'];
        if (next == null) {
            return false;
        }
        if (i == len - 1) {
            return next.isTerminal;
        }
        return Dfs(i + 1, next, word);
    }
}
}

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.AddWord(word);
 */