[LeetCode] 208. Implement Trie (Prefix Tree)(实现字典树)

Description

Implement a trie with insert, search, and startsWith methods.

Example

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // returns true
trie.search("app");     // returns false
trie.startsWith("app"); // returns true
trie.insert("app");   
trie.search("app");     // returns true

Note

  • You may assume that all inputs are consist of lowercase letters a-z.
  • All inputs are guaranteed to be non-empty strings.

Solution

这题是设计题,设计一个字典树数据结构。相关的资料可以自行百度,这里给一个简单实现。代码如下(相关地方已做了注释)

class Trie() {

    /** Initialize your data structure here. */
    private val root = TrieNode()
    private class TrieNode {
        /** 经过该节点的单词个数(本题用不上,不过存储这个可以用来统计有多少个包含前缀的单词) */
        var wordSize: Int = 1
        /** 子节点。这里用哈希表实现,可以适应不同的字符 */
        val children = hashMapOf<Char, TrieNode>()
        /** 标记是否到达一个单词的结束 */
        var end = false
    }
    

    /** Inserts a word into the trie. */
    fun insert(word: String) {
        if (word.isEmpty()) {
            return
        }

        var node = root
        for (i in word.indices) {
            val c = word[i]
            // 如果这个字符子节点存在,增加其单词计数,否则就新建一个
            if (node.children.containsKey(c)) {
                node.children.getValue(c).wordSize++
            } else {
                node.children[c] = TrieNode()
            }

            // 已经遍历到末尾,给末尾节点增加结束标志
            if (i == word.lastIndex) {
                node.children[c]?.end = true
            }

            node = node.children.getValue(c)
        }
    }

    /** Returns if the word is in the trie. */
    fun search(word: String): Boolean {
        val node = getNode(word)
        return node?.end == true
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    fun startsWith(prefix: String): Boolean {
    	return getNode(prefix) != null
    }

    /**
     * 获取到 `s` 末尾的节点,找不到则返回 `null`
     */
    private fun getNode(s: CharSequence): TrieNode? {
        if (s.isEmpty()) {
            return null
        }

        var node: TrieNode? = root
        for (c in s) {
            if (node?.children?.containsKey(c) != true) {
                return null
            }
            node = node.children[c]
        }
        return node
    }
}
原文地址:https://www.cnblogs.com/zhongju/p/13972648.html