「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」
题目描述
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
-
WordDictionary()初始化词典对象 -
void addWord(word)将word添加到数据结构中,之后可以对它进行匹配 -
bool search(word)如果数据结构中存在字符串与word匹配,则返回true;否则,返回false。word中可能包含一些'.',每个.都可以表示任何一个字母。
示例1 :
输入: ["WordDictionary","addWord","addWord","addWord","search","search","search","search"] [[],["bad"],["dad"],["mad"],["pad"],["bad"],[".ad"],["b.."]] 输出: [null,null,null,null,false,true,true,true]
解释:
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
1、hashmap
分析:使用map对内存优化,提高查找效率。
-
碰到增加单词时,逐一的将单词放入哈希表temp中即可
-
搜索单词时,对hash表中的每一个单词进行比对,长度不同的直接跳过到下一个单词,碰见长度相同的,则对两个单词中的字符逐一比对。
class WordDictionary {
public:
/** Initialize your data structure here. */
WordDictionary() {
}
/** Adds a word into the data structure. */
void addWord(string word) {
vec.push_back(word);
maps[word.size()].push_back(word);
}
/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
bool search(string word) {
if (maps[word.size()].size() == 0)
return false; //长度不匹配
int bean = 0;
for (auto i = maps[word.size()].begin(); i != maps[word.size()].end(); i++)
{
bean = 0;
for (auto item = 0; item < word.size(); item++)
{
if (*(i->begin() + item) != word[item] && word[item] != '.')
{
bean = 1; break;
}
}
if (bean == 0)
return true;
}
return false;
}
private:
vector<string> vec;
map<int, vector<string>> maps;
};
2、字典树+深度优先搜索
分析:该题与208. 实现 Trie (前缀树)大同小异,只需要对.单独处理就可以了。其他代码复用,只需要重写find辅助函数,当出现.时,需要遍历res->children_[26],该过程深入几层后,可能存在不满足情况,此时需要回溯,所以最好采用递归。
class WordDictionary {
static class PrefixTreeNode {
int end = 0; // 以该字母结束的单词的个数
PrefixTreeNode[] children = new PrefixTreeNode[26];
}
PrefixTreeNode root;
boolean searchRes = false;
public WordDictionary() {
root = new PrefixTreeNode();
}
public void addWord(String word) {
PrefixTreeNode cur = root;
for (char c : word.toCharArray()) {
if (cur.children[c - 'a'] == null) {
cur.children[c - 'a'] = new PrefixTreeNode();
}
cur = cur.children[c - 'a'];
}
cur.end++;
}
public boolean search(String word) {
PrefixTreeNode cur = root;
searchRes = false;
dfs(word.toCharArray(), cur, word.length(), 0);
return searchRes;
}
void dfs(char[] words, PrefixTreeNode cur, int len, int index) {
if (index >= len || searchRes || cur == null) return;
if (words[index] == '.') {
if (index == len - 1) {
for (PrefixTreeNode n : cur.children) {
if (n != null && n.end != 0) {
searchRes = true;
return;
}
}
} else {
for (PrefixTreeNode n : cur.children) {
if (n != null) dfs(words, n, len, index + 1);
}
}
} else if (cur.children[words[index] - 'a'] != null) {
if (index == len - 1) {
searchRes = cur.children[words[index] - 'a'].end != 0;
} else {
dfs(words, cur.children[words[index] - 'a'], len, index + 1);
}
}
}
}