676. 实现一个魔法字典
作者:互联网
题目描述:
设计一个使用单词列表进行初始化的数据结构,单词列表中的单词 互不相同 。 如果给出一个单词,请判定能否只将这个单词中一个字母换成另一个字母,使得所形成的新单词存在于你构建的字典中。
实现 MagicDictionary 类:
- MagicDictionary() 初始化对象
- void buildDict(String[] dictionary) 使用字符串数组 dictionary 设定该数据结构,dictionary 中的字符串互不相同
- bool search(String searchWord) 给定一个字符串 searchWord ,判定能否只将字符串中 一个 字母换成另一个字母,使得所形成的新字符串能够与字典中的任一字符串匹配。如果可以,返回 true ;否则,返回 false 。
提示:
- 1 <= dictionary.length <= 100
- 1 <= dictionary[i].length <= 100
- dictionary[i] 仅由小写英文字母组成
- dictionary 中的所有字符串 互不相同
- 1 <= searchWord.length <= 100
- searchWord 仅由小写英文字母组成
- buildDict 仅在 search 之前调用一次
- 最多调用 100 次 search
示例:
输入 ["MagicDictionary", "buildDict", "search", "search", "search", "search", "search"]
[[], [["hello","hallo","leetcode","judge"]], ["hello"], ["hallo"], ["hell"], ["leetcodd"], ["judge"]] 输出 [null, null, true, true, false, false]
解题思路:
- 首先,使用字典树来进行字符串的存储,在这里,字典树的初始键设为字符串长度,当search时没找到符合的长度时直接返回 false;
- 字典建立过程如下:
- 在search中,使用深度优先搜索+递归的方法,设计变量count来表示字符能被替换次数,初始值为1:
当前节点node的key与待查询字符串的第index个字符相同时,沿着node的children往下搜索;
当前节点node的key与待查询字符串的第index个字符不相同时,count减1,也沿着node的children往下搜索;
- 递归结束条件有两个:
①count的值小于0,表示递归过程中字符被替换次数超过1次,直接返回false;
②index到达待查询字符串末尾,此时根据count是否等于0来判断待查询字符串是否满足条件(count==0表示字符串中的某个字符刚好被替换一次,返回true;count>0表示与字典树中字符串相同,返回false)。
要注意的是,对于字典树中的每一层,我们应该要遍历所有的节点(相同则往下走,不同则替换次数减1后往下走)。为了简化循环,设计一个变量 f 作为信号,当前面深度优先搜索过程中找到符合条件的路径时,接下来的每一次循环都直接跳过。注意,代码中使用的是forEach方法,方法里的代码块是它的执行函数而不是循环结构,要用return来返回函数进行循环跳过,而不是break。
代码实现:
var MagicDictionary = function() { this.map = new Map(); }; /** * @param {string[]} dictionary * @return {void} */ MagicDictionary.prototype.buildDict = function(dictionary) { for(const word of dictionary){ let len = word.length; let list = new Map(); if(this.map.has(len)){ list = this.map.get(len); }else{ this.map.set(len,list); } let i=0; let cur = list; while(i<len){ if(cur.has(word[i])){ cur = cur.get(word[i]); i++; }else{ let children = new Map(); cur.set(word[i],children); i++; cur = children; } } } }; /** * @param {string} searchWord * @return {boolean} */ MagicDictionary.prototype.search = function(searchWord) { let len = searchWord.length; function dfs(searchWord,index,map,count){ if(count<0){ return false; } if(index==searchWord.length){ return count==0; } let f = false; map.forEach((value,key)=>{ if(f){ return; } if(key!==searchWord[index]){ f = dfs(searchWord,index+1,value,count-1) }else { f = dfs(searchWord,index+1,value,count); } }) return f; } if(this.map.has(len)){ let cur = this.map.get(len); return dfs(searchWord,0,cur,1); }else{ return false; } }; /** * Your MagicDictionary object will be instantiated and called as such: * var obj = new MagicDictionary() * obj.buildDict(dictionary) * var param_2 = obj.search(searchWord) */
标签:count,search,false,dictionary,676,魔法,searchWord,字符串,字典 来源: https://www.cnblogs.com/evil-shark/p/16469644.html