Algorithms first

添加与搜索单词 - 数据结构设计 · 交互式算法学习

支持 . 匹配任意字符的单词字典。

#211 · 字典树

添加与搜索单词 - 数据结构设计

Design Add and Search Words Data Structure

测试用例addWord bad,dad,mad; search .ad
树 / 图3 个关键状态
步骤 1遇到 .,分叉尝试 b、d、m。3 branches
b/d/mad
推荐

Trie + 通配 DFS

时间 普通查询 O(L)空间 O(总字符)

普通字符沿单边;遇到 . 时递归尝试当前节点所有孩子。

1class WordDictionary {2  constructor() {3    this.root = {}4  }5  addWord(w) {6    let n = this.root;7    for (const c of w) n = n[c] ??= {};8    n.end = true9  }10  search(w) {11    const dfs = (i, n) => {12      if (i === w.length) return !!n.end;13      if (w[i] !== '.') return !!n[w[i]] && dfs(i + 1, n[w[i]]);14      return Object.keys(n).some(c => c !== 'end' && dfs(i + 1, n[c]))15    };16    return dfs(0, this.root)17  }18}
多语言参考

Java · C++ · Go

来源 · CC BY-SA 4.0 ↗

这是一组同题正确实现,独立于上方当前动画方法;不同语言可能采用另一种正确策略。

1class Trie {2    Trie[] children = new Trie[26];3    boolean isEnd;4}5 6class WordDictionary {7    private Trie trie;8 9    /** Initialize your data structure here. */10    public WordDictionary() {11        trie = new Trie();12    }13 14    public void addWord(String word) {15        Trie node = trie;16        for (char c : word.toCharArray()) {17            int idx = c - 'a';18            if (node.children[idx] == null) {19                node.children[idx] = new Trie();20            }21            node = node.children[idx];22        }23        node.isEnd = true;24    }25 26    public boolean search(String word) {27        return search(word, trie);28    }29 30    private boolean search(String word, Trie node) {31        for (int i = 0; i < word.length(); ++i) {32            char c = word.charAt(i);33            int idx = c - 'a';34            if (c != '.' && node.children[idx] == null) {35                return false;36            }37            if (c == '.') {38                for (Trie child : node.children) {39                    if (child != null && search(word.substring(i + 1), child)) {40                        return true;41                    }42                }43                return false;44            }45            node = node.children[idx];46        }47        return node.isEnd;48    }49}50 51/**52 * Your WordDictionary object will be instantiated and called as such:53 * WordDictionary obj = new WordDictionary();54 * obj.addWord(word);55 * boolean param_2 = obj.search(word);56 */
交互式算法学习

从执行步骤真正理解 LeetCode 经典 150

本站整理 150 道高频算法面试题和 302 种解法。动画方法同步展示 JavaScript 与 Python;每题另提供 Java、C++ 与 Go 同题参考实现。

多形态可视化数组、矩阵、DP 表、递归树、树图、链表、栈队列堆、区间和状态机按解法选择。
动画与代码同步当前状态、步骤说明、变量和代码高亮保持一一对应,可逐步播放和回退。
适合面试复习每种方案都给出思路、时间复杂度、空间复杂度、测试用例和 LeetCode 中文原题入口。
AlgoViz Lab

添加与搜索单词 - 数据结构设计 · 解法对比

支持 . 匹配任意字符的单词字典。

测试用例
addWord bad,dad,mad; search .ad
题目分类
字典树
解法对比
2
方案 1

集合 + 模式逐词匹配

查询时扫描同长度单词,逐字符判断 . 或相等。

时间
O(NL)
空间
O(总字符)
方案 2

Trie + 通配 DFS

普通字符沿单边;遇到 . 时递归尝试当前节点所有孩子。

时间
普通查询 O(L)
空间
O(总字符)