題目
設計一個支持以下兩種操作的數據結構:
void addWord(word)
bool search(word)
search(word)
可以搜索文字或正則表達式字符串,字符串只包含字母 .
或 a-z
。
.
可以表示任何一個字母。
示例:
addWord("bad")
addWord("dad")
addWord("mad")
search("pad") // false
search("bad") // true
search(".ad") // true
search("b..") // true
思路分析
- 這道題要求字符串既可以被添加、又可以被搜索,這就意味著字符串在添加時一定要被存在某處。鍵值對存儲,我們用 Map(或對象字面量來模擬 Map)。
- 這里為了降低查找時的復雜度,我們可以考慮以字符串的長度為 key,相同長度的字符串存在一個數組中,這樣可以提高我們后續定位的效率。
- 在搜索前需要額外判斷一下,傳入的到底是普通字符串,還是正則表達式。若是普通字符串,則直接去 Map 中查找是否有這個 key;若是正則表達式,則創建一個正則表達式對象,判斷 Map 中相同長度的字符串里,是否存在一個能夠與這個正則相匹配。
代碼
class WordDictionary {
constructor() {
this.words = {}
}
addWord(word) {
if (this.words[word.length]) {
this.words[word.length].push(word)
} else {
this.words[word.length] = [word]
}
}
search(word) {
// 若該字符串長度在 Map 中對應的數組根本不存在,則可判斷該字符串不存在
if (!this.words[word.length]) {
return false
}
// 緩存目標字符串的長度
const len = word.length
// 如果字符串中不包含‘.’,那么一定是普通字符串
if (!word.includes('.')) {
return this.words[len].includes(word)
}
// 否則是正則表達式,要先創建正則表達式對象
const reg = new RegExp(word)
return this.words[len].some((item) => {
return reg.test(item)
})
}
}
const 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