Word Search II
Find all dictionary words that can be formed by moving up, down, left, or right through a board. A cell may be used only once per word.
Work through the cases
3 examplesInput notation
Space-separated dictionary words on line 1; board rows as contiguous lowercase letters on subsequent lines.Expected result
Found words in alphabetical order, separated by spaces; or none.Case 1
Input
ab abc ac bd ab cd
Expected output
ab ac bd
Case 2
Input
cat dog xx yy
Expected output
none
Case 3
Input
a aa a
Expected output
a
These notes use simplified input/output notation. The linked platform defines the method signature and judge format.
FROM IDEA TO IMPLEMENTATION
Understand the approach.
Compare the documented approaches below. Brute force, better, and optimal versions appear where available; a direct exercise may need only one approach.
A separate DFS per word repeats work on shared prefixes. Building a trie of words lets the board search walk the tree and prune dead branches. From each cell we expand to neighbors whose edge exists in the trie. Reaching a word node records the answer and sets ref to -1 so it is not reported again.
class Trie {
Trie[] children = new Trie[26];
int ref = -1;
public void insert(String w, int ref) {
Trie node = this;
for (int i = 0; i < w.length(); ++i) {
int j = w.charAt(i) - 'a';
if (node.children[j] == null) {
node.children[j] = new Trie();
}
node = node.children[j];
}
node.ref = ref;
}
}
class Solution {
private char[][] board;
private String[] words;
private List<String> ans = new ArrayList<>();
public List<String> findWords(char[][] board, String[] words) {
this.board = board;
this.words = words;
Trie tree = new Trie();
for (int i = 0; i < words.length; ++i) {
tree.insert(words[i], i);
}
int m = board.length, n = board[0].length;
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
dfs(tree, i, j);
}
}
return ans;
}
private void dfs(Trie node, int i, int j) {
int idx = board[i][j] - 'a';
if (node.children[idx] == null) {
return;
}
node = node.children[idx];
if (node.ref != -1) {
ans.add(words[node.ref]);
node.ref = -1;
}
char c = board[i][j];
board[i][j] = '#';
int[] dirs = {-1, 0, 1, 0, -1};
for (int k = 0; k < 4; ++k) {
int x = i + dirs[k], y = j + dirs[k + 1];
if (x >= 0 && x < board.length && y >= 0 && y < board[0].length && board[x][y] != '#') {
dfs(node, x, y);
}
}
board[i][j] = c;
}
}Reference code. Platform solutions may use supplied node types, imports, or collection libraries; foundational examples are complete programs.
Solutions adapted from Doocs / LeetCode contributors, licensed under CC BY-SA 4.0. Formatting changed; TypeScript versions converted to JavaScript. Supplemental implementations and approach notes added. Adapted solution material is available under the same license.