🌲 Tries

前綴樹,處理字串前綴的共享與查找。

4 題

📖 分類導讀

前綴樹 (Trie) 是專門處理字串集合的樹狀資料結構,支援高效的前綴查詢和字串搜尋。每個節點代表一個字元,從根到葉的路徑代表一個完整字串。

Notes:

  • 插入和搜尋的時間複雜度為 O(m),m 為字串長度
  • 常與 DFS/回溯結合解決複雜的字串搜尋問題

TrieNode 結構

每個節點存「往下接哪些字元」加上「是否為某個單字的結尾」。子節點有兩種存法:

  • Hash MapMap<Char, TrieNode>):字元集大或稀疏時省空間。
  • 固定陣列Array(26)):只含小寫英文字母時最快,索引 c - 'a' 直接定位。
class Trie {
    private class Node {
        val children = arrayOfNulls<Node>(26)
        var isWord = false
    }

    private val root = Node()

    fun insert(word: String) {
        var node = root
        for (c in word) {
            val i = c - 'a'
            if (node.children[i] == null) node.children[i] = Node()
            node = node.children[i]!!
        }
        node.isWord = true
    }

    fun search(word: String): Boolean = find(word)?.isWord == true

    fun startsWith(prefix: String): Boolean = find(prefix) != null

    private fun find(s: String): Node? {
        var node = root
        for (c in s) {
            val i = c - 'a'
            node = node.children[i] ?: return null
        }
        return node
    }
}

複雜度與適用

操作複雜度(k = 字串長度)
插入 / 搜尋 / 前綴查詢O(k)

複雜度只跟「這個字串多長」有關,與已存入的單字數量無關——這是 Trie 勝過「把所有字串丟進 Hash Set」的關鍵:後者能查「完整單字是否存在」,卻無法 O(k) 回答「有沒有以某前綴開頭的單字」。

TIP

訊號詞:前綴搜尋、自動補完、單字字典驗證、大量字串共享前綴想省空間。若再加上「萬用字元 .」就配合 DFS/回溯在節點上分支搜尋。

跨倉庫導讀

#208Implement Trie (Prefix Tree)Medium★★★★★⏱ O(m)#211Design Add and Search Words Data StructureMedium★★★★★⏱ O(m)#212Word Search IIHard★★★★★⏱ O(M * N * 4^L)#2707Extra Characters in a StringMedium★★★★★⏱ O(n^2 + m)