• [100天算法】-实现 Trie(day 41)


    题目描述

    1. 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。
    2. 示例:
    3. Trie trie = new Trie();
    4. trie.insert("apple");
    5. trie.search("apple"); // 返回 true
    6. trie.search("app"); // 返回 false
    7. trie.startsWith("app"); // 返回 true
    8. trie.insert("app");
    9. trie.search("app"); // 返回 true
    10. 说明:
    11. 你可以假设所有的输入都是由小写字母 a-z 构成的。
    12. 保证所有输入均为非空字符串。
    13. 来源:力扣(LeetCode)
    14. 链接:https://leetcode-cn.com/problems/implement-trie-prefix-tree
    15. 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    思路

    熟悉一下 Trie 的概念就可以了。

    https://medium.com/basecs/trying-to-understand-tries-3ec6bede0014

    复杂度分析

    • 时间复杂度:$O(L)$,L 是字符串长度, insert search startsWith 操作都是。
    • 空间复杂度:$O(M^{L})$,L 是字符串长度,M 是字符集中字符个数,如本题中 M 就是 26。

    代码

    TypeScript Code

    class TrieNode {
        value: string;
        children: Array;
    
        constructor(value) {
            this.value = value;
            this.children = Array(26);
        }
    }
    
    class Trie {
        private root: TrieNode;
    
        constructor() {
            this.root = this._getTrieNode('');
        }
    
        private _getTrieNode(value: string): TrieNode {
            return new TrieNode(value);
        }
    
        private _char2Index(char: string): number {
            return char.toLowerCase().charCodeAt(0) - 97;
        }
    
        insert(word: string): void {
            let crawl: TrieNode = this.root;
            for (let char of word) {
                const index: number = this._char2Index(char);
                if (!crawl.children[index]) {
                    crawl.children[index] = this._getTrieNode('');
                }
                crawl = crawl.children[index];
            }
            crawl.value = word;
        }
    
        search(word: string): boolean {
            let crawl: TrieNode = this.root;
            for (let char of word) {
                const index: number = this._char2Index(char);
                if (!crawl.children[index]) return false;
                crawl = crawl.children[index];
            }
            return crawl.value === word;
        }
    
        startsWith(prefix: string): boolean {
            let crawl: TrieNode = this.root;
            for (let char of prefix) {
                const index: number = this._char2Index(char);
                if (!crawl.children[index]) return false;
                crawl = crawl.children[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)
     */

    JavaScript Code

    class TrieNode {
        constructor(val) {
            this.value = val;
            this.pointers = Array(26);
        }
    }
    
    class Trie {
        constructor() {
            this.root = this._getTrieNode('');
        }
    
        /**
         * @param {string} val
         */
        _getTrieNode(val) {
            return new TrieNode(val);
        }
    
        /**
         * @param {string} char
         * @returns {number}
         */
        _char2Index(char) {
            return char.toLowerCase().charCodeAt(0) - 97;
        }
    
        /**
         * Inserts a word into the trie.
         * @param {string} word
         * @return {void}
         */
        insert(word) {
            let crawl = this.root;
            for (let char of word) {
                const index = this._char2Index(char);
                if (!crawl.pointers[index]) {
                    crawl.pointers[index] = this._getTrieNode('');
                }
                crawl = crawl.pointers[index];
            }
            // Store the word in the last TrieNode as an end mark.
            crawl.value = word;
        }
    
        /**
         * Returns if the word is in the trie.
         * @param {string} word
         * @return {boolean}
         */
        search(word) {
            let crawl = this.root;
            for (let char of word) {
                const index = this._char2Index(char);
                if (!crawl.pointers[index]) return false;
    
                crawl = crawl.pointers[index];
            }
            // If it has a stored value, it is the last TrieNode, i.e., the desired word is found.
            // Otherwise, the word doesn't exist in Trie.
            return !!crawl.value;
        }
    
        /**
         * Returns if there is any word in the trie that starts with the given prefix.
         * @param {string} prefix
         * @return {boolean}
         */
        startsWith(prefix) {
            let crawl = this.root;
            for (let char of prefix) {
                const index = this._char2Index(char);
                if (!crawl.pointers[index]) return false;
    
                crawl = crawl.pointers[index];
            }
            return true;
        }
    }

    输入输出

    Nodejs

    const __main__ = function () {
        const readline = require('readline');
        const rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });
    
        console.log('******输入******');
        rl.prompt();
        const lines = [];
        rl.on('line', line => lines.push(line));
    
        rl.on('close', () => {
            console.log('\n******输出******');
    
            const test = (operations, params) => {
                if (operations[0] === 'Trie') {
                    const trie = new Trie();
                    const output = [null];
                    for (let i = 1; i < operations.length; i++) {
                        const res = trie[operations[i]](...params[i]);
                        output.push(res === void 0 ? null : res);
                    }
                    console.log(output);
                } else {
                    console.log(Array(operations.length).fill(null));
                }
            };
    
            while (lines.length >= 2) {
                const params = lines.splice(0, 2);
                test(...params.map(el => JSON.parse(el)));
            }
        });
    };
  • 相关阅读:
    自定义终结符:EOF
    06496基于PHP的在线考试系统设计与实现-计算机毕业设计源码
    Android R窗口Window的requestlayout过程大揭秘
    20230919在WIN10下使用python3将PDF文档转为DOCX格式的WORD文档
    Structured Streaming系列-6、事件时间窗口分析
    Ribbon
    OpenGLES:绘制一个混色旋转的3D圆柱
    数据库设计详细教程上篇(数据库设计流程)
    2023二建备考第二天Day02
    Vue.js快速入门:构建现代Web应用
  • 原文地址:https://blog.csdn.net/xiaoshun007/article/details/134033827