题目:https://leetcode-cn.com/problems/add-and-search-word-data-structure-design/
思路:
1. add 时采用回溯建立前缀树,在单词的最后一个字符增加完时,标记节点isWord=true;
2. search是采用回溯遍历前缀树
3. search时遇到“.” 字符,遍历所有子节点,直到找到。
4.search 时若遇到普通字母,从子节点中找到value与字母相等的节点,继续往下查找下一个字母。否之,返回false;
/**
* Initialize your data structure here.
*/
var WordDictionary = function() {
this.node={childdren:[],value:null};
};
/**
* Adds a word into the data structure.
* @param {string} word
* @return {void}
*/
WordDictionary.prototype.addWord = function(word) {
let backTrack = (curIndex, node)=>{
if(curIndex===word.length){
node.isWord=true;
return;
}
let targetChild = node.childdren.find(child=>child.value === word[curIndex]);
if(targetChild){
backTrack(curIndex+1,targetChild);
}else{
targetChild={value:word[curIndex], childdren:[]}
node.childdren.push(targetChild);
backTrack(curIndex+1,targetChild);
}
}
backTrack(0,this.node);
};
/**
* Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter.
* @param {string} word
* @return {boolean}
*/
WordDictionary.prototype.search = function(word) {
console.log(word);
let backTrack = (curIndex,node)=>{
if(curIndex === word.length && node.isWord){
return true;
}else if(curIndex === word.length){
return false
}else if(node.childdren.length===0){
return false;
}
if(word[curIndex]==="."){
return node.childdren.some(child=>{
return backTrack(curIndex+1,child);
})
}else{
const targetNode = node.childdren.find(child=>child.value===word[curIndex]);
if(targetNode){
return backTrack(curIndex+1,targetNode)
}else{
return false;
}
}
}
return backTrack(0,this.node);
};
/**
* Your WordDictionary object will be instantiated and called as such:
* var obj = new WordDictionary()
* obj.addWord(word)
* var param_2 = obj.search(word)
*/
实现Trie (前缀树)
题目:https://leetcode-cn.com/problems/implement-trie-prefix-tree/submissions/
思路:插入单词时,建立树;
每个树节点,包含3部分信息:
1. 存储的字母
2. 是否有单词在这个节点结束
3. 子节点
树建立过程:
1. 从根节点的子节点开始,向下逐序查找单词的每个字母。
2. 当前节点的子节点找不到目标字母时,为当前节点新增一个子节点,存储目标字母。
3. 直到单词的最后,将节点标记为有单词
树建立回溯算法:
1. 正确的解:单词 index === 单词length,单词遍历完
2. 每个节点的解空间:所有子节点,若查不到,新增一个子节点
3. 剪枝函数:无
代码对应:insert 函数
/**
* Initialize your data structure here.
*/
var Trie = function() {
this.node = {value:null,childdren:[]};
};
/**
* Inserts a word into the trie.
* @param {string} word
* @return {void}
*/
Trie.prototype.insert = function(word) {
let backTrack=(curIndex,node)=>{
if(curIndex===word.length){
node.isWord=true;
return;
}
let targetChild = node.childdren.find(child=>child.value===word[curIndex]);
if(!targetChild){
targetChild = {value:word[curIndex],childdren:[]} ;
node.childdren.push(targetChild);// push the new create child node
}
backTrack(curIndex+1,targetChild);
}
backTrack(0, this.node);
};
/**
* Returns if the word is in the trie.
* @param {string} word
* @return {boolean}
*/
Trie.prototype.search = function(word) {
const backTrack = (curIndex,node)=>{
if(curIndex===word.length && node.isWord){
return true;
}else if(curIndex===word.length){
return false;
}
const targetChild = node.childdren.find(child=>child.value===word[curIndex]);
if(!targetChild) return false;
return backTrack(curIndex+1,targetChild);
}
return backTrack(0,this.node);
};
/**
* Returns if there is any word in the trie that starts with the given prefix.
* @param {string} prefix
* @return {boolean}
*/
Trie.prototype.startsWith = function(prefix) {
const backTrack = (curIndex,node)=>{
if(curIndex===prefix.length){
return true;
}
const targetChild = node.childdren.find(child=>child.value===prefix[curIndex]);
if(!targetChild) return false;
return backTrack(curIndex+1,targetChild);
}
return backTrack(0,this.node);
};
/**
* Your Trie object will be instantiated and called as such:
* var obj = new Trie()
* obj.insert(word)
* var param_2 = obj.search(word)
* var param_3 = obj.startsWith(prefix)
*/