Stay button 208-- achieve Trie (Prefix Tree)

This question is the main structure of the prefix tree data structure nodes to help answer questions.

The original title

Implement a Trie (prefix tree), comprising insert, search, and startsWith these three operations.

Example:

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

Description:

  • You can assume that all inputs are constituted by the lowercase letters az.
  • To ensure that all inputs are non-empty string.

原题url:https://leetcode-cn.com/problems/implement-trie-prefix-tree/

Problem-solving

Meaning prefix tree

We use this prefix tree data structure, mainly used in the 在字符串数据集中搜索单词scene, but for such a scenario, we can use 平衡树and 哈希表, and hash tables can O(1)find the key time. So why prefix trees?

There are three reasons:

  1. Prefix tree can find all the keys have agreed prefix.
  2. Prefix tree may be enumerated by a string dictionary data set.
  3. You may be used when the prefix tree in memory a plurality of keys with the same prefix less space, only O(m)time complexity, where m is a bond length. Find the key in balancing the tree it takes O(m log n), where n is the number of keys inserted; and the hash table size increases, there will be a lot of conflict, the time complexity may increase O(n).

Prefix tree node structure configuration

Since it is a tree, and certainly there is the root node. As for the node structure, you need to have the following characteristics:

  1. Up to R number of links pointing to child nodes, wherein each link corresponding to a letter of the alphabet in the data set. In this problem it is assumed to R 26, the number of Latin small letter.
  2. Boolean field to specify the node keys corresponding to the end or just prefix key.

Let's look at the code node structure:

class TrieNode {

    TrieNode[] nodes;

    boolean isEnd;

    public TrieNode() {
        // 26个小写英文字母
        nodes = new TrieNode[26];
        // 当前是否已经结束
        isEnd = false;
    }
        
        /**
         * 当前节点是否包含字符 ch
         */
    public boolean contains(char ch) {
        return nodes[ch - 'a'] != null;
    }
        
        /**
         * 设置新的下一个节点
         */
    public TrieNode setNode(char ch, TrieNode node) {
            // 判断当前新的节点是否已经存在
        TrieNode tempNode = nodes[ch - 'a'];
                // 如果存在,就直接返回已经存在的节点
        if (tempNode != null) {
            return tempNode;
        }

        // 否则就设置为新的节点,并返回
        nodes[ch - 'a'] = node;
        return node;
    }
        
        /**
         * 获取 ch 字符
         */
    public TrieNode getNode(char ch) {
        return nodes[ch - 'a'];
    }
        
        /**
         * 设置当前节点为结束
         */
    public void setIsEnd() {
        isEnd = true;
    }

    /**
         * 当前节点是否已经结束
         */
    public boolean isEnd() {
        return isEnd;
    }
}

Then there is the real prefix tree structure:

class Trie {

    /**
         * 根节点
         */
    TrieNode root;

    /** Initialize your data structure here. */
    public Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    public void insert(String word) {
        TrieNode before = root;
        TrieNode node;
                // 遍历插入单词中的每一个字母
        for (int i = 0; i < word.length(); i++) {
            node = new TrieNode();
            node = before.setNode(word.charAt(i), node);
            before = node;
        }
                // 设置当前为终点
        before.setIsEnd();
    }
    
    /** Returns if the word is in the trie. */
    public boolean search(String word) {
        TrieNode before = root;
        TrieNode temp;
                // 遍历查找
        for (int i = 0; i < word.length(); i++) {
            temp = before.getNode(word.charAt(i));
            if (temp == null) {
                return false;
            }
            before = temp;
        }
                // 且最后一个节点也是终点
        return before.isEnd();
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    public boolean startsWith(String prefix) {
        TrieNode before = root;
        TrieNode temp;
                // 遍历查找
        for (int i = 0; i < prefix.length(); i++) {
            temp = before.getNode(prefix.charAt(i));
            if (temp == null) {
                return false;
            }
            before = temp;
        }
        return true;
    }
}

Submit OK, when executed by: 43 msmemory consumption: 55.3 MBAlthough only defeated the 87.40%submission, but tried it the fastest that code, and my method in time basically no difference, it is time to submit test cases had not so much it.

to sum up

This question is above my answer process, I do not know if you understand. This question may require specialized to understand how the use of the prefix tree, which can contribute to the structural configuration of the prefix tree.

Are interested can visit my blog or follow me number of public, headline number, maybe there will be surprises.

https://death00.github.io/

Public number: Jian Cheng Road

Guess you like

Origin www.cnblogs.com/death00/p/12164983.html