携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
题目链接:676. 实现一个魔法字典
题目描述
设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。
实现 MagicDictionary 类:
MagicDictionary()初始化对象void buildDict(String[] dictionary)使用字符串数组dictionary设定该数据结构,dictionary中的字符串互不相同bool search(String searchWord)给定一个字符串searchWord,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回true;否则,返回false。
提示:
dictionary[i]仅由小写英文字母组成dictionary中的所有字符串 互不相同searchWord仅由小写英文字母组成buildDict仅在search之前调用一次- 最多调用
100次search
示例 1:
输入
["MagicDictionary", "buildDict", "search", "search", "search", "search"]
[[], [["hello", "leetcode"]], ["hello"], ["hhllo"], ["hell"], ["leetcoded"]]
输出
[null, null, false, true, false, false]
解释
MagicDictionary magicDictionary = new MagicDictionary();
magicDictionary.buildDict(["hello", "leetcode"]);
magicDictionary.search("hello"); // 返回 False
magicDictionary.search("hhllo"); // 将第二个 'h' 替换为 'e' 可以匹配 "hello" ,所以返回 True
magicDictionary.search("hell"); // 返回 False
magicDictionary.search("leetcoded"); // 返回 False
整理题意
题目给定一个字符串数组 dictionary,然后每次给出一个单词 searchWord,需要我们判断是否可以通过改变 searchWord 的中的一个字符使得 searchWord 与字符串数组 dictionary 中某一个字符串相同。
需要注意的是 必须 改变
searchWord的中的一个字符,且仅能改变一个字符。
解题思路分析
由于题目数据范围较小,我们可以对于每次查询的 searchWord 在字符串数组 dictionary 中进行暴力匹配,查找字符串数组 dictionary 中的字符串是否存在与 searchWord 长度相同且仅有一个字符不相同的字符串。
具体实现
- 将给定字符串数组
dictionary进行存储; - 对于每次给定的
searchWord,遍历字符串数组dictionary,匹配与searchWord长度相同且仅有一个字符不相同的字符串。 - 如果匹配成功返回
true,否则返回false。
复杂度分析
- 时间复杂度:,其中
n是数组dictionary的长度,l是数组dictionary中字符串的平均长度,q是函数search(searchWord)的调用次数。 - 空间复杂度:,即为数组需要使用的空间。
代码实现
class MagicDictionary {
private:
vector<string> s;
public:
MagicDictionary() {
s.clear();
}
void buildDict(vector<string> dictionary) {
s = dictionary;
}
bool search(string searchWord) {
int len = searchWord.length();
int n = s.size();
for(int i = 0; i < n; i++){
//当长度不匹配时直接跳过
if(s[i].length() != len) continue;
//f记录不相同的字符个数
int f = 0;
for(int j = 0; j < len; j++){
if(s[i][j] != searchWord[j]) f++;
//如果有两个字符不相同也可以直接跳过
if(f >= 2) break;
}
if(f == 1) return true;
}
return false;
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/
总结
- 由于该题数据范围较小,采用暴力枚举匹配的方法更优。同时该题如果扩大数据范围,需要使用字典树来优化枚举,在字典树上进行搜索。在查询时,我们可以使用递归 + 回溯的方法进行判断。
- 在匹配字符串时,对于长度不相等的字符串可以跳过,同时采用一个变量记录不同字符的个数,当不同字符的个数超过
1个时也可以直接跳过,从而减少循环次数。 - 测试结果:
结束语
世界上没有人是完美的,每个人都有优点和缺点,不必因为一些缺憾而郁郁寡欢,也不要因一时错过而过多地埋怨自己。只有学会欣赏自己的优点和长处,充分接纳自己,才能散发出更多的光芒!新的一天,加油!