📖Blog :《LeetCode 211.添加与搜索单词(数据结构设计) - JavaScript》javascript
题目描述:设计一个支持如下两种操做的数据结构:java
void addWord(word) bool search(word)
search(word)
能够搜索文字或正则表达式字符串,字符串只包含字母 .
或 a-z
。 .
能够表示任何一个字母。node
示例:python
addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true
你能够假设全部单词都是由小写字母 a-z
组成的。git
看到题目,第一个直觉是将单词都存放在数组中。每次匹配的时候,循环遍历数组,查看是否存在能够匹配的字符串。github
可是这种暴力法的时间复杂度高,在平台上没法 ac。所以要想其余的方法。正则表达式
有一种很是巧妙的正则表达式方法:全部的单词再也不存放在数组中,而是经过先后添加“#”来进行分割(标识单词界限)。数组
例如依次添加了“bad”、“mad”。那么内部字符串是:“#bad#mad#”。当咱们要匹配目标串“.ad”时,只须要在目标串先后添加“#”便可。数据结构
在 leetcode 上,本题的 js 写法没法 ac,可是 python3 的能够。应该是断定条件比较宽松,下面的代码 ac 花费了 2924ms。this
# ac地址: https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/ # 原文地址:https://xxoo521.com/2020-02-29-add-and-search-word/ from re import search class WordDictionary: def __init__(self): """ Initialize your data structure here. """ self.words = '#' def addWord(self, word: str) -> None: """ Adds a word into the data structure. """ self.words += (word + '#') def search(self, word: str) -> bool: """ Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. """ return bool(search('#' + word + '#', self.words))
对于记录/查找单词的情景,有种数据结构很是高效:Trie。咱们能够构造一棵字典树,每次调用 addWord 时候,将单词存入字典树。
注意:当调用 search 进行查找的时候,若是当前字符不是.
,那么就按照字典树的查找逻辑;不然,因为是通配符,要遍历当前的节点的 next 中的全部字符,这个过程和 DFS 同样。
代码以下:
// ac地址: https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/ // 原文地址:https://xxoo521.com/2020-02-29-add-and-search-word/ var TrieNode = function() { this.next = {}; this.isEnd = false; }; /** * Initialize your data structure here. */ var WordDictionary = function() { this.root = new TrieNode(); }; /** * @param {string} word * @return {void} */ WordDictionary.prototype.addWord = function(word) { if (!word.length) return; let node = this.root; for (let i = 0; i < word.length; ++i) { if (!node.next[word[i]]) { node.next[word[i]] = new TrieNode(); } node = node.next[word[i]]; } node.isEnd = true; }; /** * @param {string} word * @return {boolean} */ WordDictionary.prototype.search = function(word) { if (!word.length) return false; return this.dfs(this.root, word); }; /** * @param {TrieNode} root * @param {string} word * @return {boolean} */ WordDictionary.prototype.dfs = function(root, word) { const length = word.length; let node = root; for (let i = 0; i < length; ++i) { const ch = word[i]; // 如果通配符,则尝试遍历全部的状况(DFS) if (ch === ".") { const keys = Reflect.ownKeys(node.next); for (const key of keys) { const found = this.dfs(node.next[key], word.slice(i + 1)); if (found) return true; } return false; } if (!node.next[ch]) { return false; } node = node.next[ch]; } return node.isEnd; };
如有错误,欢迎指正。若对您有帮助,请给个「关注+点赞」,您的支持是我更新的动力 👇