LeetCode 211.添加与搜索单词
Posted 想名真难
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 211.添加与搜索单词相关的知识,希望对你有一定的参考价值。
请你设计一个数据结构,支持 添加新单词 和 查找字符串是否与任何先前添加的字符串匹配 。
实现词典类 WordDictionary :
WordDictionary() 初始化词典对象
void addWord(word) 将 word 添加到数据结构中,之后可以对它进行匹配
bool search(word) 如果数据结构中存在字符串与 word 匹配,则返回 true ;否则,返回 false 。word 中可能包含一些 '.' ,每个 . 都可以表示任何一个字母。
1 <= word.length <= 25
addWord 中的 word 由小写英文字母组成
search 中的 word 由 '.' 或小写英文字母组成
最多调用 10^4 次 addWord 和 search
WordDictionary wordDictionary = new WordDictionary();
wordDictionary.addWord("bad");
wordDictionary.addWord("dad");
wordDictionary.addWord("mad");
wordDictionary.search("pad"); // 返回 False
wordDictionary.search("bad"); // 返回 True
wordDictionary.search(".ad"); // 返回 True
wordDictionary.search("b.."); // 返回 True
犹豫不决, 没有思路的时候就先想想暴力法,
- addWord的时候把单词加入到一个集合中,
- 到搜索的时候, 如果入参的单词含有 "." , 那就把这个 "." 换成 "a ~ z"的所有字母, 枚举出所有可能的组合,
- 如果这个组合中有和集合中重复的元素, 那就说明存在, 返回ture
- 如果集合中和枚举出的所有情况都没有交集, 说明不存在, 返回false
这个是2种暴力法的实现, 时间复杂度取决于点的数量, 如果有n个 ".", 那就是O(26^n), 到LeetCode上运行 果然出现了超时,
// 暴力法1
class WordDictionary
var dictionarySet = Set<String>.init()
init()
func addWord(_ word: String)
dictionarySet.update(with: word)
func search(_ word: String) -> Bool
// 暴力法,把work所有的情况枚举出来放到一个集合中
let wordSet = changeWorkToSet(word: word)
// 取2个集合的并集, 结果为空, 说明不包含; 结果有值, 说明存在
let resultSet = dictionarySet.intersection(wordSet)
if resultSet.isEmpty
return false
else
return true
func changeWorkToSet(word : String) -> Set<String>
// 包含点,把一个点换成具体的字符,然后递归调用自己,直到所有的.都消失
if word.contains(".")
var set = Set<String>.init()
let startIndex = word.firstIndex(of: ".")!
let endIndex = word.index(startIndex, offsetBy: 1)
let alphabet: [String] = ["a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x",
"y", "z"]
for replaceChar in alphabet
var newWord = word
newWord.replaceSubrange(startIndex..<endIndex, with: replaceChar)
let resultSet = changeWorkToSet(word: newWord)
for resultWord in resultSet
set.update(with: resultWord)
return set
else
// 不包含点, 直接返回一个set,set中只有一个元素
return Set.init(arrayLiteral: word)
// 暴力法2, 计算出一个结果就会调, 没有必要把所有情况都枚举出来
class WordDictionary
var dictionarySet = Set<String>.init()
// 应不应该继续遍历, 每一个新的查询开始的时候设置为true
var shouldContinue = true
init()
func addWord(_ word: String)
dictionarySet.update(with: word)
func search(_ word: String) -> Bool
shouldContinue = true
var result = false
// 暴力法,把work所有的情况枚举出来进行回调判断
changeWorkToComplete(word: word) resultString in
if self.dictionarySet.contains(resultString)
result = true
self.shouldContinue = false
return result
func changeWorkToComplete(word : String, complete: @escaping (String) -> Void)
// 只要找到一个,结束遍历
if !shouldContinue
return
// 包含点,把一个点换成具体的字符,然后递归调用自己,直到所有的.都消失
if word.contains(".")
let startIndex = word.firstIndex(of: ".")!
let endIndex = word.index(startIndex, offsetBy: 1)
let alphabet: [String] = ["a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x",
"y", "z"]
for replaceChar in alphabet
var newWord = word
newWord.replaceSubrange(startIndex..<endIndex, with: replaceChar)
changeWorkToComplete(word: newWord, complete: complete)
else
// 不包含点了, 直接回调
complete(word)
以上是关于LeetCode 211.添加与搜索单词的主要内容,如果未能解决你的问题,请参考以下文章
leetcode 211. 添加与搜索单词 - 数据结构设计 解题报告
LeetCode211. 添加与搜索单词 - 数据结构设计(相关话题:Trie前缀树)