public class Solution {
private char[][] board;
private List<String> result = new ArrayList<String>();
public List<String> findWords(char[][] board, String[] words) {
TrieNode root = new TrieNode();
for (String str : words) {
buildTrie(str, root);
}
int row = board.length;
if (row == 0) {
return result;
}
int col = board[0].length;
this.board = board;
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
if (root.child[(int)board[r][c] - (int)'a'] != null)
find(r, c, "", root.child[(int)board[r][c] - (int)'a']);
}
}
return result;
}
private void find(int r, int c, String str, TrieNode root) {
if (root.isWord) {
if (!result.contains(str + board[r][c]))
result.add(str + board[r][c]);
}
char tmp = board[r][c];
board[r][c] = '*';
str = str + tmp;
if (r > 0 && board[r - 1][c] != '*' && root.child[board[r - 1][c] - 'a'] != null) {
find(r - 1, c, str, root.child[(int)board[r - 1][c] - (int)'a']);
}
if (r + 1 < board.length && board[r + 1][c] != '*' && root.child[board[r + 1][c] - 'a'] != null) {
find(r + 1, c, str, root.child[(int)board[r + 1][c] - (int)'a']);
}
if (c > 0 && board[r][c - 1] != '*' && root.child[board[r][c - 1] - 'a'] != null) {
find(r, c - 1, str, root.child[(int)board[r][c - 1] - (int)'a']);
}
if (c + 1 < board[0].length && board[r][c + 1] != '*' && root.child[board[r][c + 1] - 'a'] != null) {
find(r, c + 1, str, root.child[(int)board[r][c + 1] - (int)'a']);
}
board[r][c] = tmp;
}
private void buildTrie (String word, TrieNode root) {
if (word.length() == 0) {
root.isWord = true;
return;
}
char tmp = word.charAt(0);
if (root.child[(int)tmp - (int)'a'] == null) {
root.child[(int)tmp - (int)'a'] = new TrieNode();
}
buildTrie(word.substring(1), root.child[(int)tmp - (int)'a']);
}
class TrieNode {
TrieNode[] child = new TrieNode[26];
boolean isWord;
TrieNode() {
isWord = false;
}
}
}