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
.
class MagicDictionary:
def __init__(self):
"""
Initialize your data structure here.
"""
def _patterns(self, word):
return [word[:i] + '*' + word[i + 1:] for i in range(len(word))]
def buildDict(self, dictionary: List[str]) -> None:
self.words = set(dictionary)
self.counter = Counter(
p for word in dictionary for p in self._patterns(word))
def search(self, searchWord: str) -> bool:
for p in self._patterns(searchWord):
if self.counter[p] > 1 or (self.counter[p] == 1 and searchWord not in self.words):
return True
return False
# Your MagicDictionary object will be instantiated and called as such:
# obj = MagicDictionary()
# obj.buildDict(dictionary)
# param_2 = obj.search(searchWord)
class MagicDictionary {
List<char[]> dict;
/** Initialize your data structure here. */
public MagicDictionary() {
dict = new ArrayList<>();
}
public void buildDict(String[] dictionary) {
for (String item : dictionary) {
dict.add(item.toCharArray());
}
}
public boolean search(String searchWord) {
char[] target = searchWord.toCharArray();
for (char[] item : dict) {
if (item.length != target.length) {
continue;
}
int diff = 0;
for (int i = 0; i < target.length; i++) {
if (target[i] != item[i]) {
diff += 1;
}
}
if (diff == 1) {
return true;
}
}
return false;
}
}
class MagicDictionary {
private Set<String> words;
private Map<String, Integer> counter;
/** Initialize your data structure here. */
public MagicDictionary() {
words = new HashSet<>();
counter = new HashMap<>();
}
public void buildDict(String[] dictionary) {
for (String word : dictionary) {
words.add(word);
for (String p : patterns(word)) {
counter.put(p, counter.getOrDefault(p, 0) + 1);
}
}
}
public boolean search(String searchWord) {
for (String p : patterns(searchWord)) {
int cnt = counter.getOrDefault(p, 0);
if (cnt > 1 || (cnt == 1 && !words.contains(searchWord))) {
return true;
}
}
return false;
}
private List<String> patterns(String word) {
List<String> res = new ArrayList<>();
char[] chars = word.toCharArray();
for (int i = 0; i < chars.length; ++i) {
char c = chars[i];
chars[i] = '*';
res.add(new String(chars));
chars[i] = c;
}
return res;
}
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
*/
class MagicDictionary {
public:
/** Initialize your data structure here. */
MagicDictionary() {
}
void buildDict(vector<string> dictionary) {
for (string word : dictionary)
{
words.insert(word);
for (string p : patterns(word)) ++counter[p];
}
}
bool search(string searchWord) {
for (string p : patterns(searchWord))
{
if (counter[p] > 1 || (counter[p] == 1 && !words.count(searchWord))) return true;
}
return false;
}
private:
unordered_set<string> words;
unordered_map<string, int> counter;
vector<string> patterns(string word) {
vector<string> res;
for (int i = 0; i < word.size(); ++i)
{
char c = word[i];
word[i] = '*';
res.push_back(word);
word[i] = c;
}
return res;
}
};
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary* obj = new MagicDictionary();
* obj->buildDict(dictionary);
* bool param_2 = obj->search(searchWord);
*/
type MagicDictionary struct {
words map[string]bool
counter map[string]int
}
/** Initialize your data structure here. */
func Constructor() MagicDictionary {
return MagicDictionary{
words: make(map[string]bool),
counter: make(map[string]int),
}
}
func (this *MagicDictionary) BuildDict(dictionary []string) {
for _, word := range dictionary {
this.words[word] = true
for _, p := range patterns(word) {
this.counter[p]++
}
}
}
func (this *MagicDictionary) Search(searchWord string) bool {
for _, p := range patterns(searchWord) {
if this.counter[p] > 1 || (this.counter[p] == 1 && !this.words[searchWord]) {
return true
}
}
return false
}
func patterns(word string) []string {
var res []string
for i := 0; i < len(word); i++ {
res = append(res, word[:i]+"."+word[i+1:])
}
return res
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* obj := Constructor();
* obj.BuildDict(dictionary);
* param_2 := obj.Search(searchWord);
*/