# 算法 leetcode212 单词搜索 II

image.png

image.png

m == board.length
n == board[i].length
1 <= m, n <= 12
board[i][j] 是一个小写英文字母
1 <= words.length <= 3 * 104
1 <= words[i].length <= 10
words[i] 由小写英文字母组成
words 中的所有字符串互不相同

``````class Solution {
int[][] dirs = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
public List<String> findWords(char[][] board, String[] words) {
//构造前缀树，也是字典树
Trie trie = new Trie();
for (String word : words) {
trie.insert(word);
}
//结果集
Set<String> ans = new HashSet<>();
for (int i = 0; i < board.length; ++i) {
for (int j = 0; j < board[0].length; ++j) {
//从每个点进行dfs
dfs(board, trie, i, j, ans);
}
}
return new ArrayList<>(ans);
}

public void dfs(char[][] board, Trie now, int i1, int j1, Set<String> ans) {
//若当前节点char不是前缀树的第一层children的值，直接减枝
if (!now.children.containsKey(board[i1][j1])) {
return;
}
char ch = board[i1][j1];
//获取对应字符下的前缀树
now = now.children.get(ch);
if (!"".equals(now.word)) {
}

//将刚读过的字符置为#标记
board[i1][j1] = '#';
//对board[i][j]字符 上下左右移动，对后面点 dfs
for (int[] dir : dirs) {
int i2 = i1 + dir[0], j2 = j1 + dir[1];
if (i2 >=0 && i2 < board.length && j2 >=0 && j2<board[0].length) {
dfs(board, now, i2, j2, ans);
}
}
board[i1][j1] = ch;
}

class Trie {
String word;
Map<Character, Trie> children;
boolean isWord;

public Trie() {
this.word = "";
this.children = new HashMap<Character, Trie>();
}

public void insert(String word) {
Trie cur = this;
for (int i = 0; i < word.length(); ++i) {
char c = word.charAt(i);
if (!cur.children.containsKey(c)) {
cur.children.put(c, new Trie());
}
cur = cur.children.get(c);
}
cur.word = word;
}
}

}
``````