Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

实现 Trie (前缀树)-208 #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sl1673495 opened this issue May 5, 2020 · 0 comments
Open

实现 Trie (前缀树)-208 #14

sl1673495 opened this issue May 5, 2020 · 0 comments
Labels
复习 * 1 复习了一遍的题目 数据结构

Comments

@sl1673495
Copy link
Owner

sl1673495 commented May 5, 2020

实现一个 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  构成的。
保证所有输入均为非空字符串。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/implement-trie-prefix-tree
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

Trie (也叫前缀树、字典树),是一种可以实现快速查找字符串前缀的数据结构。它为单词中的每一个字母开辟一个新的 TrieNode,这个 TrieNode 的结构如下:

let TrieNode = function () {
  this.next = new Map();
  this.isEnd = false;
};

这里的 next 代表这个字母后面可以继续追加的组合,比如 applead 它们共用 a 这个 TrieNode,而 anext 表里又保存了 pd 的 TrieNode。

在插入的时候,会循环构建这个 TrieNode 树,而在单词的末尾字母的 TrieNode 节点上,会把 isEnd 属性置为 true,用以标识这可以作为一个单词的结尾(注意,是可以作为,并不一定到此为止,因为可能有 adadc 这种两个单词的情况)

而查询某种前缀的单词也就变得很简单,利用前缀中的每个字母不断的循环下去,找到前缀中最后一个单词的 TrieNode,再看它的next 表里有哪些组合,即可找出某个前缀下排列组合的所有可能性。

image

单词 "leet" 在 Trie 树中的表示
image

题解

let TrieNode = function () {
  this.next = new Map();
  this.isEnd = false;
};

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

/**
 * Inserts a word into the trie.
 * @param {string} word
 * @return {void}
 */
Trie.prototype.insert = function (word) {
  let node = this.root;

  for (let i = 0; i < word.length; i++) {
    let { next } = node;
    let trieNode = next.get(word[i]);
    if (!trieNode) {
      trieNode = new TrieNode();
      next.set(word[i], trieNode);
    }
    node = trieNode;

    if (i === word.length - 1) {
      node.isEnd = true;
    }
  }
};

/**
 * Returns if the word is in the trie.
 * @param {string} word
 * @return {boolean}
 */
Trie.prototype.search = function (word) {
  let node = this.root;

  for (let i = 0; i < word.length; i++) {
    let { next } = node;
    let trieNode = next.get(word[i]);
    if (!trieNode) {
      return false;
    }
    node = trieNode;
  }
  return node.isEnd;
};

/**
 * 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 node = this.root;

  for (let i = 0; i < prefix.length; i++) {
    let { next } = node;
    let trieNode = next.get(prefix[i]);
    if (!trieNode) {
      return false;
    }
    node = trieNode;
  }
  return true;
};

/**
 * Your Trie object will be instantiated and called as such:
 * let obj = new Trie()
 * obj.insert(word)
 * let param_2 = obj.search(word)
 * let param_3 = obj.startsWith(prefix)
 */
@sl1673495 sl1673495 added 待复习 看题解或者做出来很艰难的,需要回顾。 数据结构 labels May 5, 2020
@sl1673495 sl1673495 added 复习 * 1 复习了一遍的题目 and removed 待复习 看题解或者做出来很艰难的,需要回顾。 labels May 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
复习 * 1 复习了一遍的题目 数据结构
Projects
None yet
Development

No branches or pull requests

1 participant