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 strings dictionary
.bool search(String searchWord)
Returns true
if you can change exactly one character in searchWord
to match any string in the data structure, otherwise returns false
.Example:
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
## Magic Dictionary Implementation
This problem requires implementing a `MagicDictionary` class that can be initialized with a list of distinct words and then efficiently determine if a given `searchWord` can be matched to any word in the dictionary by changing exactly one character.
### Naive Approach
A straightforward but potentially inefficient approach is to iterate through the dictionary for each search query and compare each word with the `searchWord`. For each word in the dictionary, count the number of differing characters. If exactly one character differs, return `true`. This approach has a time complexity of O(N*M), where N is the number of words in the dictionary and M is the maximum length of a word.
```python
class MagicDictionary:
def __init__(self):
self.dictionary = []
def buildDict(self, dictionary: list[str]) -> None:
self.dictionary = dictionary
def search(self, searchWord: str) -> bool:
for word in self.dictionary:
if len(word) != len(searchWord):
continue
diff_count = 0
for i in range(len(word)):
if word[i] != searchWord[i]:
diff_count += 1
if diff_count == 1:
return True
return False
To improve the efficiency, we can use a hash map to store words grouped by their length. This will reduce the number of words we need to compare against. When searching, we only compare the searchWord
against words in the dictionary that have the same length.
class MagicDictionary:
def __init__(self):
self.word_map = {}
def buildDict(self, dictionary: list[str]) -> None:
for word in dictionary:
length = len(word)
if length not in self.word_map:
self.word_map[length] = []
self.word_map[length].append(word)
def search(self, searchWord: str) -> bool:
length = len(searchWord)
if length not in self.word_map:
return False
for word in self.word_map[length]:
diff_count = 0
for i in range(length):
if word[i] != searchWord[i]:
diff_count += 1
if diff_count == 1:
return True
return False
searchWord
and K is the number of words in the dictionary that have the same length as searchWord
. In the best case, O(1) if no words of the same length exist in the dictionary.word_map
.search
method should always return false
.searchWord
is empty, the search
method should return false
.search
method should only compare words of the same length as the searchWord
.search
method should return false
if the searchWord
is exactly the same as a word in the dictionary, as it requires a change of one character.