Copy class Solution {
public List<String> findWords(char[][] board, String[] words) {
List<String> res = new ArrayList<String>();
// edge cases
if (board.length == 0 || board[0].length == 0 || words.length == 0) {
return res;
}
// build trie
TrieNode root = new TrieNode();
root.build(words);
for (int r = 0; r < board.length; r++) {
for (int c = 0; c < board[0].length; c++) {
dfs(board, r, c, root, res);
}
}
return res;
}
private void dfs(char[][] board, int r, int c, TrieNode node, List<String> res) {
// out of boundary?
if (r < 0 || c < 0 || r >= board.length || c >= board[0].length) return;
// visited in this word? current char not in trie? return
int pos = board[r][c] - 'a';
if (board[r][c] == '#' || node.next[pos] == null) return;
// continue, mark visited
char curr = board[r][c];
board[r][c] = '#';
// find word
if (node.next[pos].word != null) {
res.add(node.next[pos].word);
node.next[pos].word = null;
}
// adjacent chars
dfs(board, r+1, c, node.next[pos], res);
dfs(board, r-1, c, node.next[pos], res);
dfs(board, r, c+1, node.next[pos], res);
dfs(board, r, c-1, node.next[pos], res);
// resume visited mark
board[r][c] = curr;
}
}
class TrieNode {
public TrieNode[] next;
String word;
public TrieNode() {
next = new TrieNode[26];
}
public void insert(String s, int index) {
if (index == s.length()) {
this.word = s;
return;
}
int i = s.charAt(index) - 'a';
if (next[i] == null) next[i] = new TrieNode();
next[i].insert(s, index+1);
}
public void build(String[] words){
for (String w : words) {
insert(w, 0);
}
}
}
// build a trie, node with a string
// walk board, current char in trie? continue : return;
//board[r][c] - 'a'