实现一个魔法字典
难度:
标签:
题目描述
代码结果
运行时间: 39 ms, 内存: 16.3 MB
/*
* 思路:
* 1. 使用HashSet来存储字典中的单词。
* 2. 使用流的方式遍历每个字符并替换。
*/
import java.util.HashSet;
import java.util.Set;
import java.util.stream.IntStream;
public class MagicDictionary {
private Set<String> dictionary;
public MagicDictionary() {
dictionary = new HashSet<>();
}
public void buildDict(String[] dictionary) {
for (String word : dictionary) {
this.dictionary.add(word);
}
}
public boolean search(String searchWord) {
return IntStream.range(0, searchWord.length())
.anyMatch(i -> searchWord.chars()
.mapToObj(c -> (char) c)
.filter(c -> c != searchWord.charAt(i))
.anyMatch(c -> {
char[] chars = searchWord.toCharArray();
chars[i] = c;
return dictionary.contains(new String(chars));
}));
}
}
解释
方法:
这个题解首先在构建字典阶段(buildDict),将所有输入的单词按照长度分类存储到一个字典中,其中键是单词的长度,值是具有该长度的单词集合。这样做的目的是为了在搜索阶段能够快速定位到与待搜索单词长度相同的单词集合,从而降低搜索范围。在搜索阶段(search),如果待搜索单词的长度在构建的字典中找不到对应的键,则直接返回False。否则,遍历与搜索词长度相同的单词集合,通过逐字符比对的方式计算两个单词之间的不同字符数。如果恰好有一个字符不同,则返回True,表示可以通过改变一个字符使得单词存在于字典中。如果遍历完都没有找到,返回False。
时间复杂度:
O(N * L)
空间复杂度:
O(N * L)
代码细节讲解
🦆
为什么选择按单词长度来组织字典,而不是其他属性如字母顺序或哈希值?
▷🦆
在实现search方法时,有没有考虑使用更高效的算法来减少单词间比对的次数?
▷🦆
buildDict方法中使用set存储同长度的单词有什么特殊考虑?例如考虑到重复单词或者其他因素吗?
▷🦆
search方法中,如果遇到多个单词长度相同但每个单词中有多处字符不同,这种情况下如何优化以减少不必要的比对?
▷相关问题
实现 Trie (前缀树)
Trie(发音类似 "try")或者说 前缀树 是一种树形数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。
请你实现 Trie 类:
Trie()
初始化前缀树对象。void insert(String word)
向前缀树中插入字符串word
。boolean search(String word)
如果字符串word
在前缀树中,返回true
(即,在检索之前已经插入);否则,返回false
。boolean startsWith(String prefix)
如果之前已经插入的字符串word
的前缀之一为prefix
,返回true
;否则,返回false
。
示例:
输入 ["Trie", "insert", "search", "search", "startsWith", "insert", "search"] [[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]] 输出 [null, null, true, false, true, null, true] 解释 Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // 返回 True trie.search("app"); // 返回 False trie.startsWith("app"); // 返回 True trie.insert("app"); trie.search("app"); // 返回 True
提示:
1 <= word.length, prefix.length <= 2000
word
和prefix
仅由小写英文字母组成insert
、search
和startsWith
调用次数 总计 不超过3 * 104
次
词典中最长的单词
给出一个字符串数组 words
组成的一本英语词典。返回 words
中最长的一个单词,该单词是由 words
词典中其他单词逐步添加一个字母组成。
若其中有多个可行的答案,则返回答案中字典序最小的单词。若无答案,则返回空字符串。
示例 1:
输入:words = ["w","wo","wor","worl", "world"] 输出:"world" 解释: 单词"world"可由"w", "wo", "wor", 和 "worl"逐步添加一个字母组成。
示例 2:
输入:words = ["a", "banana", "app", "appl", "ap", "apply", "apple"] 输出:"apple" 解释:"apply" 和 "apple" 都能由词典中的单词组成。但是 "apple" 的字典序小于 "apply"
提示:
1 <= words.length <= 1000
1 <= words[i].length <= 30
- 所有输入的字符串
words[i]
都只包含小写字母。