实现一个带有buildDict
, 以及 search
方法的魔法字典。
对于buildDict
方法,你将被给定一串不重复的单词来构建一个字典。
对于search
方法,你将被给定一个单词,并且判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。
示例 1:
Input: buildDict(["hello", "leetcode"]), Output: Null Input: search("hello"), Output: False Input: search("hhllo"), Output: True Input: search("hell"), Output: False Input: search("leetcoded"), Output: False
注意:
- 你可以假设所有输入都是小写字母
a-z
。 - 为了便于竞赛,测试所用的数据量很小。你可以在竞赛结束后,考虑更高效的算法。
- 请记住重置MagicDictionary类中声明的类变量,因为静态/类变量会在多个测试用例中保留。 请参阅这里了解更多详情。
思路:这道题的标签是Trie,就是要构建字典前缀树,但是自己编写了很久也没有debug正确,最终放弃了。发现如果用hashset可以非常简单的编写出来。
具体思路为把所有的string放入hashset中,然后每次改变一个string中的一个字符(会改变26次,对应a-z,如果改变的是自己本身的字符,那么不做处理),然后再hashset中搜索答案,如果存在就返回true,如果遍历完所有string,对每个string都改变了26次字符都没有在hashset中发现,那么返回false。
参考代码:
class MagicDictionary {
public:
/** Initialize your data structure here. */
MagicDictionary() {
}
/** Build a dictionary through a list of words */
void buildDict(vector<string> dict) {
for (auto &s : dict) s_set.insert(s);
}
/** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */
bool search(string word) {
for (int i = 0; i < word.size();i++) {
char letter = word[i];
for (int j = 0; j < 26; j++) {
word[i] = 'a' + j;
if (letter != word[i]) {
if (s_set.find(word) != s_set.end()) return true;
}
}
word[i] = letter;
}
return false;
}
private:
unordered_set<string> s_set;
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dict);
* bool param_2 = obj.search(word);
*/