3

前端实现字典树

本文演示前端实现字典树,同时这也是LeetCode第208题,medium难度的题。

题目概述

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:
Trie trie = new Trie();
trie.insert("apple");
trie.search("apple"); // 返回 true
trie.search("app"); // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");
trie.search("app"); // 返回 true

说明:
你可以假设所有的输入都是由小写字母 a-z 构成的。
保证所有输入均为非空字符串。

代码实现

树节点

首先声明树节点,每个节点有一个值、26个孩子节点,用{}对象表示,其中每个对象存的是TreeNode。
还有一个isWord属性用来存当前有没有以当前节点的val字符结尾的单词。

class TreeNode{
    constructor(val) {
        this.val = val
        this.isWord = false;
        this.chilrden = {}
    }

}

字典树构造函数

初始化字典树,只有根元素,根元素也是一个节点,所以用TreeNode()
同时根元素没有val,故TreeNode不需要传参数。
暂时没有子元素,所以它的children属性暂时是: {} 空对象
也没有一个单词是不包含任何字母的,所以根的isWord属性也是走默认的false

/**
 * Initialize your data structure here.
 */
var Trie = function() {
    this.root = new TreeNode();
};

实现insert方法

/**
 * Inserts a word into the trie.
 * @param {string} word
 * @return {void}
 */
Trie.prototype.insert = function(word) {
    let curNode = this.root;
    let arr = word.split('')
    for(let i = 0; i < arr.length; i++){
        let isHasChildNode = curNode.chilrden[arr[i]]
        // 没有子节点的话,就要创建一个以当前字符为val的子节点
        if(!isHasChildNode){
            curNode.chilrden[arr[i]] = new TreeNode(arr[i])
        }
        curNode = curNode.chilrden[arr[i]]
        // 遍历到最后一个字符所对应的节点,将这个节点的isWord属性设为true。
        if(i === arr.length - 1){
            curNode.isWord = true;
        }
    }
};

实现search方法

/**
 * Returns if the word is in the trie.
 * @param {string} word
 * @return {boolean}
 */
Trie.prototype.search = function(word) {
    let curNode = this.root;
    let arr = word.split('')
    for(let i = 0; i < arr.length; i++){
        if(!curNode.chilrden[arr[i]]){
            return false;
        }
        curNode = curNode.chilrden[arr[i]]
        // 搜素到最后一个字符,根据isWord属性判断是否曾经存过这个单词
        if(i === arr.length - 1){
            return curNode.isWord === true
        }
    }
};

实现startswith方法

/**
 * 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) {
    let curNode = this.root;
    let arr = prefix.split('')
    for(let i = 0; i < arr.length; i++){
        // 凡是查找的单词的中间某个字符,没有找到节点的,返回false
        if(!curNode.chilrden[arr[i]]){
            return false;
        }
        curNode = curNode.chilrden[arr[i]]
    }
    // 每个字符都找到了节点,返回true
    return true
};

测试代码

let trie = new Trie();
trie.insert("apple");
console.log(trie.search("apple")); // 返回 true
console.log(trie.search("app")); // 返回 false
console.log(trie.startsWith("app")); // 返回 true
trie.insert("app");
console.log(trie.search("app")); // 返回 true

我的前端算法库

地址:https://github.com/cunzaizhuy...
目前已经刷了200多道题,题解都在里面。

欢迎star和交流。

fe-algo.jpeg


飞叶_前端
1.4k 声望139 粉丝

Wasm和emscripten技术交流群:939206522