https://blog.csdn.net/m0_46202073/article/details/107253959
https://leetcode.cn/problems/implement-trie-prefix-tree/solution/trie-tree-de-shi-xian-gua-he-chu-xue-zhe-by-huwt/
208. 实现 Trie (前缀树)
/** @lc app=leetcode.cn id=208 lang=javascript** [208] 实现 Trie (前缀树)*/// @lc code=startvar TrieNode =function(){ // 节点this.isEnd = false;this.next = Array(26);}var Trie = function () { // 前缀树this.node= new TrieNode();};/*** @param {string} word* @return {void}*/Trie.prototype.insert = function (word) {let node = this.node;for (let w of word) {const index = w.charCodeAt() - 'a'.charCodeAt()if (!node.next[index]) {node.next[index] = new Trie();}node = node.next[index]}node.isEnd = true;};/*** @param {string} word* @return {boolean}*/Trie.prototype.search = function (word) {let node = this;for (let w of word) {const index = w.charCodeAt() - 'a'.charCodeAt()if (!node.next[index]) return false;node = node.next[index]}return node.isEnd};/*** @param {string} prefix* @return {boolean}*/Trie.prototype.startsWith = function (prefix) {let node = this;for (let w of prefix) {const index = w.charCodeAt() - 'a'.charCodeAt()if (!node.next[index]) return false;node = node.next[index]}return true;};/*** 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)*/// @lc code=end
820. 单词的压缩编码
var minimumLengthEncoding = function (words) {words.sort((a, b) => { //需要先排序,让长的单词先插入return b.length - a.length;})let sum = 0;let trie = new Trie();for (let word of words) {sum += trie.insert(word);}return sum;};var TrieNode =function(){ // 节点this.next = Array(26);}class Trie {constructor() {this.node= new TrieNode();}insert(word) {let node = this.node;let flag = false;for (let i = word.length - 1; i >= 0; i--) { //倒着插入const index = word[i].charCodeAt() - 'a'.charCodeAt();if (!node.next[index]) {flag = true; //如果有新建节点则node.next[index] = new TrieNode();}node = node.next[index];}return flag ? word.length + 1 : 0;}}
211. 添加与搜索单词 - 数据结构设计
前几道题的search都是迭代的方式,这有一点弊端:“cur一条路走到黑”,但有时我们需要走一个分叉的路,去尝试更多的可能。
所以接下来用递归的方式去搜索。
var TrieNode = function () {this.next = Array(26);this.isEnd = false;}var WordDictionary = function () {this.node = new TrieNode();};/*** @param {string} word* @return {void}*/WordDictionary.prototype.addWord = function (word) {let node = this.node;for (let w of word) {const index = w.charCodeAt() - 'a'.charCodeAt();if (!node.next[index]) {node.next[index] = new TrieNode();}node = node.next[index];}node.isEnd = true;};/*** @param {string} word* @return {boolean}*/WordDictionary.prototype.search = function (word) {return match(word, this.node, 0);};function match(word, node, start) {if (start === word.length) {return node.isEnd;}if (word[start] === '.') {for (let i = 0; i < 26; i++) {if (node.next[i] != null && match(word, node.next[i], start + 1)) {return true;}}return false;} else {const index = word[start].charCodeAt() - 'a'.charCodeAt();return node.next[index] != null && match(word, node.next[index], start + 1)}}
676. 实现一个魔法字典
与211题类似,
var TrieNode = function () {this.next = Array(26);this.isEnd = false;}var MagicDictionary = function () {this.node = new TrieNode();};/*** @param {string[]} dictionary* @return {void}*/MagicDictionary.prototype.buildDict = function (dictionary) {for (let dic of dictionary) {let node = this.node;for (let w of dic) {const index = w.charCodeAt() - 'a'.charCodeAt();if (!node.next[index]) {node.next[index] = new TrieNode();}node = node.next[index];}node.isEnd = true;}};/*** @param {string} searchWord* @return {boolean}*/MagicDictionary.prototype.search = function (searchWord) {return match(searchWord, this.node, 0, true)};var match = function (word, node, start, hasChance) {if (start === word.length) {return node.isEnd && !hasChance;}//这样写,当字典树中有"hello"和"hallo"时,search("hello")会返回false。// const index = word[start].charCodeAt() - 'a'.charCodeAt();// if (!node.next[index]) {// if (hasChance) {// for (let i = 0; i < 26; i++) {// if (node.next[i] != null && match(word, node.next[i], start + 1, false)) {// return true;// }// }// }// return false;// } else {// return match(word, node.next[index], start + 1, hasChance)// }// 所以改为一次for(26)的遍历。for (let i = 0; i < 26; i++) {if (node.next[i]) {const index = word[start].charCodeAt() - 'a'.charCodeAt();if (index === i && match(word, node.next[i], start + 1, hasChance)) {return true;} else if (index !== i && hasChance && match(word, node.next[i], start + 1, false)) {return true;}}}return false;}
