leetcode 208.实现 Trie (前缀树) | 刷题打卡

460 阅读2分钟

题目链接

前缀树

基本概念

什么是前缀树?

前缀树(Trie)又叫字典树,是一种树形的数据结构,用于高效地存储和检索字符串数据集中的键。这一数据结构有相当多的应用情景,例如自动补完和拼写检查。

前缀树和普通的数有点区别,需要一个字段表示,是否已经结束

普通树的结点的定义:

class TreeNode {
	val: any;
  children: TreeNode[];
}

前缀树结点的定义:

class TreeNode {
  isEnd: boolean; // 表示该结点是否是一个串的结束
  children:  { [key: string]: any }; // 孩子用对象表示,用当前字符作为对象的key
}

前缀树张什么样子?

假设有3个字符串aboutandapple构建成一棵前缀树

构建起来就是这样的

image-20210909135943745

思路

知道了前缀树的构成,代码写起来就很清晰

  • 插入:声明一个指针node,遍历要插入的字符串,看当前字符是否在当前节点中存在,不存在则创建一个新节点,然后将指针指向这个新节点,遍历完成后,给指针指向的最后一个节点加上属性node.isEnd = ture
  • 查找:遍历这个字符串,每个字符都看看在前缀树中存不存在,不存在直接返回false,存在并且遍历到最后有isEnd标识结束则为找到,返回true
  • 前缀查找:流程和查找一样,但有无isEnd标识都行

代码

class Trie {
    children: { [key: string]: any };

    constructor() {
        this.children = {};
    }
  
		/**
  	* 向前缀树中插入当前字符串
  	**/
    insert(word: string): void {
        let node = this.children;
        for (const ch of word) {
            if (!node[ch]) { 
                node[ch] = {}; // 如果字符不存在,创建一个新的节点
            }
            node = node[ch]; // 指向下一个字符
        }
        node.isEnd = true; // 标识当前字符串已结束
    }

  	/**
  	* 查看前缀树中是否含有目标字符串作为前缀
  	**/
    serachPrefix(word: string): { [key: string]: any } | false {
        let node = this.children;
        for (const ch of word) {
            if (!node[ch]) {
                return false; // 找不到当前字符,直接返回false
            }
            node = node[ch]; // 指向下一个字符
        }
        return node; // 返回字符串最后一个字符对应的节点
    }

  	/**
  	* 查看前缀树中包含要查找的目标字符串
  	**/
    search(word: string): boolean {
        const node = this.serachPrefix(word);
        return node && !!node.isEnd; // 最后一个节点存在并且有结束标识
    }

  	/**
  	* 查看前缀树中是否含有目标字符串作为前缀
  	**/
    startsWith(prefix: string): boolean {
        return this.serachPrefix(prefix) as boolean; // 最后一个节点存在,不管有没有结束标识
    }
}