LeetCode-in-All

208. Implement Trie (Prefix Tree)

Medium

A trie (pronounced as “try”) or prefix tree is a tree data structure used to efficiently store and retrieve keys in a dataset of strings. There are various applications of this data structure, such as autocomplete and spellchecker.

Implement the Trie class:

Example 1:

Input

["Trie", "insert", "search", "search", "startsWith", "insert", "search"]
[[], ["apple"], ["apple"], ["app"], ["app"], ["app"], ["app"]]

Output: [null, null, true, false, true, null, true]

Explanation:

Trie trie = new Trie();
trie.insert("apple"); trie.search("apple"); // return True
trie.search("app"); // return False
trie.startsWith("app"); // return True
trie.insert("app");
trie.search("app"); // return True 

Constraints:

Solution

class TrieNode {
    public $children;
    public $isWord;

    function __construct() {
        $this->children = array_fill(0, 26, null);
        $this->isWord = false;
    }
}

class Trie {
    private $root;
    private $startWith;

    function __construct() {
        $this->root = new TrieNode();
        $this->startWith = false;
    }

    /**
     * @param String $word
     * @return NULL
     */
    public function insert($word) {
        $this->insertInternal($word, $this->root, 0);
    }

    private function insertInternal($word, $root, $idx) {
        if ($idx == strlen($word)) {
            $root->isWord = true;
            return;
        }
        $index = ord($word[$idx]) - ord('a');
        if ($root->children[$index] == null) {
            $root->children[$index] = new TrieNode();
        }
        $this->insertInternal($word, $root->children[$index], $idx + 1);
    }

    /**
     * @param String $word
     * @return Boolean
     */
    public function search($word) {
        return $this->searchInternal($word, $this->root, 0);
    }

    private function searchInternal($word, $root, $idx) {
        if ($idx == strlen($word)) {
            $this->startWith = true;
            return $root->isWord;
        }
        $index = ord($word[$idx]) - ord('a');
        if ($root->children[$index] == null) {
            $this->startWith = false;
            return false;
        }
        return $this->searchInternal($word, $root->children[$index], $idx + 1);
    }

    /**
     * @param String $prefix
     * @return Boolean
     */
    public function startsWith($prefix) {
        $this->search($prefix);
        return $this->startWith;
    }
}
/**
 * Your Trie object will be instantiated and called as such:
 * $obj = Trie();
 * $obj->insert($word);
 * $ret_2 = $obj->search($word);
 * $ret_3 = $obj->startsWith($prefix);
 */