Algorithms first
单词搜索 II · 交互式算法学习
在字符网格中找出词表里所有可由相邻格组成的单词。
#212 · 字典树
单词搜索 II
Word Search II
board = [[o,a,a,n],[e,t,a,e],[i,h,k,r],[i,f,l,v]], words = [oath,pea,eat,rain]矩阵3 个关键状态
步骤 1Trie 根只允许 o、p、e、r 起步。
prefix pruneo0,0
a0,1
a0,2
n0,3
e1,0
t1,1
a1,2
e1,3
i2,0
h2,1
k2,2
r2,3
i3,0
f3,1
l3,2
v3,3
推荐
Trie 剪枝 + 一次网格 DFS
时间
O(mn·4^L)空间 O(词表字符数)词表建 Trie,网格路径只沿仍可能形成单词的前缀继续。
1function findWords(b, words) {2 const root = {};3 for (const w of words) {4 let n = root;5 for (const c of w) n = n[c] ??= {};6 n.word = w7 }8 const out = [];9 10 function dfs(r, c, n) {11 const ch = b[r]?.[c],12 next = n[ch];13 if (!next) return;14 if (next.word) {15 out.push(next.word);16 delete next.word17 }18 b[r][c] = '#';19 for (const [dr, dc] of [20 [1, 0],21 [-1, 0],22 [0, 1],23 [0, -1]24 ]) dfs(r + dr, c + dc, next);25 b[r][c] = ch;26 if (!Object.keys(next).length) delete n[ch]27 }28 for (let r = 0; r < b.length; r++)29 for (let c = 0; c < b[0].length; c++) dfs(r, c, root);30 return out;31}多语言参考
来源 · CC BY-SA 4.0 ↗Java · C++ · Go
这是一组同题正确实现,独立于上方当前动画方法;不同语言可能采用另一种正确策略。
1class Trie {2 Trie[] children = new Trie[26];3 int ref = -1;4 5 public void insert(String w, int ref) {6 Trie node = this;7 for (int i = 0; i < w.length(); ++i) {8 int j = w.charAt(i) - 'a';9 if (node.children[j] == null) {10 node.children[j] = new Trie();11 }12 node = node.children[j];13 }14 node.ref = ref;15 }16}17 18class Solution {19 private char[][] board;20 private String[] words;21 private List<String> ans = new ArrayList<>();22 23 public List<String> findWords(char[][] board, String[] words) {24 this.board = board;25 this.words = words;26 Trie tree = new Trie();27 for (int i = 0; i < words.length; ++i) {28 tree.insert(words[i], i);29 }30 int m = board.length, n = board[0].length;31 for (int i = 0; i < m; ++i) {32 for (int j = 0; j < n; ++j) {33 dfs(tree, i, j);34 }35 }36 return ans;37 }38 39 private void dfs(Trie node, int i, int j) {40 int idx = board[i][j] - 'a';41 if (node.children[idx] == null) {42 return;43 }44 node = node.children[idx];45 if (node.ref != -1) {46 ans.add(words[node.ref]);47 node.ref = -1;48 }49 char c = board[i][j];50 board[i][j] = '#';51 int[] dirs = {-1, 0, 1, 0, -1};52 for (int k = 0; k < 4; ++k) {53 int x = i + dirs[k], y = j + dirs[k + 1];54 if (x >= 0 && x < board.length && y >= 0 && y < board[0].length && board[x][y] != '#') {55 dfs(node, x, y);56 }57 }58 board[i][j] = c;59 }60}交互式算法学习
从执行步骤真正理解 LeetCode 经典 150
本站整理 150 道高频算法面试题和 302 种解法。动画方法同步展示 JavaScript 与 Python;每题另提供 Java、C++ 与 Go 同题参考实现。
AlgoViz Lab
单词搜索 II · 解法对比
在字符网格中找出词表里所有可由相邻格组成的单词。
- 测试用例
board = [[o,a,a,n],[e,t,a,e],[i,h,k,r],[i,f,l,v]], words = [oath,pea,eat,rain]- 题目分类
- 字典树
- 解法对比
- 2
每个单词单独回溯
对词表每个单词从每个格子启动 DFS。
- 时间
O(W·mn·4^L)- 空间
O(L)
Trie 剪枝 + 一次网格 DFS
词表建 Trie,网格路径只沿仍可能形成单词的前缀继续。
- 时间
O(mn·4^L)- 空间
O(词表字符数)