- 字典树
- 回溯
- 剪枝
class Solution {
int[] dx = {0, 0, -1, 1};
int[] dy = {-1, 1, 0, 0};
boolean[][] visited = null;
List<String > result = new ArrayList<>();
public List<String> findWords(char[][] board, String[] words) {
TrieTree trieTree=initTrie(words);
visited = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
backtrack(i, j, board, board[i][j]+"",trieTree.root);
}
}
return result;
}
private TrieTree initTrie(String[] words) {
TrieTree trieTree = new TrieTree();
TrieTree.Node root = new TrieTree.Node();
trieTree.setRoot(root);
for (int i = 0; i < words.length; i++) {
TrieTree.Node start = root;
for (int j = 0; j < words[i].length(); j++) {
char ij = words[i].charAt(j);
if (start.getNext().get(ij) == null) {
start.getNext().put(ij, new TrieTree.Node());
}
start = start.getNext().get(ij);
}
start.setEnd(true);
start.setWord(words[i]);
}
return trieTree;
}
public void backtrack(int i, int j, char[][] board, String res, TrieTree.Node trieTree) {
Character letter = board[i][j];
TrieTree.Node currNode = trieTree.getNext().get(letter);
if (currNode!=null&&currNode.isEnd()) {
if (!result.contains(currNode.word)){
result.add(currNode.word);
}
}
if (trieTree.getNext().containsKey(board[i][j])) {
visited[i][j] = true;
for (int k = 0; k < dx.length; k++) {
int tempi = i + dx[k];
int tempj = j + dy[k];
if ((tempi >= 0 && tempj >= 0 && tempi < board.length && tempj < board[0].length) && !visited[tempi][tempj]) {
backtrack(tempi, tempj, board, res+board[tempi][tempj], currNode);
}
}
visited[i][j] = false;
if (currNode.getNext().isEmpty()) {
trieTree.getNext().remove(letter);
}
}
return ;
}
public static class TrieTree {
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
Node root;
public boolean has(String res){
Node lastNode=root;
for (int i = 0; i < res.length(); i++) {
lastNode =lastNode.getNext().get(res.charAt(i));
if (null==lastNode){
return false;
}
}
return lastNode.isEnd();
}
public boolean startWith(String res){
Node lastNode=root;
for (int i = 0; i < res.length(); i++) {
lastNode =lastNode.getNext().get(res.charAt(i));
if (null==lastNode){
return false;
}
}
return true;
}
public static class Node {
public Node() {
}
public Node(char value, boolean isEnd) {
this.value = value;
this.isEnd = isEnd;
}
Map<Character, Node> next = new HashMap<>();
char value;
boolean isEnd;
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
String word;
public Map<Character, Node> getNext() {
return next;
}
public void setNext(Map<Character, Node> next) {
this.next = next;
}
public char getValue() {
return value;
}
public void setValue(char value) {
this.value = value;
}
public boolean isEnd() {
return isEnd;
}
public void setEnd(boolean end) {
isEnd = end;
}
}
}
}