Design a data structure that is initialized with a list of different words. Provided a string, you should determine if you can change exactly one character in this string to match any word in the data structure.
Implement the MagicDictionary
class:
MagicDictionary()
Initializes the object.void buildDict(String[] dictionary)
Sets the data structure with an array of distinct stringsdictionary
.bool search(String searchWord)
Returnstrue
if you can change exactly one character insearchWord
to match any string in the data structure, otherwise returnsfalse
.
Example 1:
Input ["MagicDictionary", "buildDict", "search", "search", "search", "search"] [[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]] Output [null, null, false, true, false, false] Explanation MagicDictionary magicDictionary = new MagicDictionary(); magicDictionary.buildDict(["hello", "leetcode"]); magicDictionary.search("hello"); // return False magicDictionary.search("hhllo"); // We can change the second 'h' to 'e' to match "hello" so we return True magicDictionary.search("hell"); // return False magicDictionary.search("leetcoded"); // return False
Constraints:
1 <= dictionary.length <= 100
1 <= dictionary[i].length <= 100
dictionary[i]
consists of only lower-case English letters.- All the strings in
dictionary
are distinct. 1 <= searchWord.length <= 100
searchWord
consists of only lower-case English letters.buildDict
will be called only once beforesearch
.- At most
100
calls will be made tosearch
.
题目链接:https://leetcode.com/problems/implement-magic-dictionary/
题目大意:实现一个数据结构,如果待查询的字符串只改变一个字符即可与集合中某一字符串匹配则返回true
题目分析:对集合中的字符串建trie,查询时在任意位置都可以跳过一次,dfs即可,一般trie会用boolean值标记当前节点是不是结尾,本题需要存字符串长度,用boolean值可能会出现只匹配到前缀的情况
65ms,时间击败57.67
class MagicDictionary {
class TrieNode {
TrieNode[] nxt;
int len;
TrieNode() {
this.nxt = new TrieNode[26];
this.len = 0;
}
}
class Trie {
TrieNode root;
Trie() {
this.root = new TrieNode();
}
void insert(String word) {
TrieNode p = this.root;
int len = word.length();
for (int i = 0; i < len; i++) {
int idx = word.charAt(i) - 'a';
if (p.nxt[idx] == null) {
p.nxt[idx] = new TrieNode();
}
p = p.nxt[idx];
}
p.len = len;
}
boolean magicQuery(String word, int pos, TrieNode cur, int chg) {
TrieNode p = cur;
int len = word.length();
for (int i = pos; i < len; i++) {
int idx = word.charAt(i) - 'a';
if (chg == 0) {
boolean ok = false;
for (int j = 0; j < 26 && !ok; j++) {
if (p.nxt[j] != null) {
ok |= magicQuery(word, i + 1, p.nxt[j], (j == idx) ? 0 : 1);
}
}
return ok;
} else if (p.nxt[idx] != null) {
p = p.nxt[idx];
}
}
return p.len == len && chg != 0;
}
boolean search(String word) {
return magicQuery(word, 0, this.root, 0);
}
}
private Trie trie;
public MagicDictionary() {
this.trie = new Trie();
}
public void buildDict(String[] dictionary) {
for (String s : dictionary) {
this.trie.insert(s);
}
}
public boolean search(String searchWord) {
return this.trie.search(searchWord);
}
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
*/