package main import ( "fmt" ) type TrieNode struct { children map[rune]*TrieNode isEnd bool } type Trie struct { root *TrieNode } func NewTrie() *Trie { return &Trie{root: &TrieNode{children: make(map[rune]*TrieNode)}} } func (t *Trie) Insert(word string) { node := t.root for _, ch := range word { if node.children[ch] == nil { node.children[ch] = &TrieNode{children: make(map[rune]*TrieNode)} } node = node.children[ch] } node.isEnd = true } func (t *Trie) StartsWith(prefix string) []string { var results []string var dfs func(node *TrieNode, path []rune) node := t.root for _, ch := range prefix { if node.children[ch] == nil { return results } node = node.children[ch] } dfs = func(node *TrieNode, path []rune) { if node.isEnd { results = append(results, prefix+string(path)) } for ch, child := range node.children { dfs(child, append(path, ch)) } } dfs(node, []rune{}) return results } func main() { trie := NewTrie() words := []string{"apple", "app", "application", "apt", "banana"} for _, w := range words { trie.Insert(w) } result := trie.StartsWith("app") fmt.Println(result) }
The code inserts words into a trie and searches for all words starting with "app". The words "app", "apple", and "application" start with "app". "apt" does not start with "app" but with "ap" only, so it is excluded.
The root node counts as 1. The words share prefixes: "cat" and "car" share 'c' and 'a'. "cart" extends "car" by one letter. "dog" is separate. Counting nodes: root(1), c(2), a(3), t(4), r(5), t(6), d(7), o(8), g(9).
func (t *Trie) StartsWith(prefix string) []string {
var results []string
var dfs func(node *TrieNode, path []rune)
node := t.root
for _, ch := range prefix {
if node.children[ch] == nil {
return results
}
node = node.children[ch]
}
dfs = func(node *TrieNode, path []rune) {
if node.isEnd {
results = append(results, string(path))
}
for ch, child := range node.children {
dfs(child, append(path, ch))
}
}
dfs(node, []rune{})
return results
}The DFS appends only the suffix path to results without adding the prefix. So the returned words are missing the prefix "bat". For example, it returns ["", "h", "man"] instead of ["bat", "bath", "batman"].
All given words start with the prefix "pre" so the search returns all of them.
Tries store shared prefixes once, so common parts of words are not duplicated, saving memory compared to storing each word separately in a hash map.