# 单词搜索系列问题

CSDN：单词搜索系列问题

## LeetCode 79. 单词搜索

for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (p(i, j, 0, str, board)) {
return true;
}
}
}


public static boolean p(int i, int j, int index, char[] str, char[][] board) {
if (index == str.length) {
return true;
}
if (i >= board.length || j >= board[0].length || i < 0 || j < 0 ) {
return false;
}
if (board[i][j] == '0') {
return false;
}
......
}


public static boolean p(int i, int j, int index, char[] str, char[][] board) {
.......
char c = board[i][j];
board[i][j] = '0';
if (str[index] == c) {
boolean p1 = p(i + 1, j, index + 1, str, board);
if (p1) {
board[i][j] = c;
return true;
}
boolean p2 = p(i, j + 1, index + 1, str, board);
if (p2) {
board[i][j] = c;
return true;
}
boolean p3 = p(i - 1, j, index + 1, str, board);
if (p3) {
board[i][j] = c;
return true;
}
boolean p4 = p(i, j - 1, index + 1, str, board);
if (p4) {
board[i][j] = c;
return true;
}

}
board[i][j] = c;
return false;
}


board[i][j] = '0'


str[index] == c


public class LeetCode_0079_WordSearch {
// 不能走重复路
public static boolean exist(char[][] board, String word) {
char[] str = word.toCharArray();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (p(i, j, 0, str, board)) {
return true;
}
}
}
return false;
}

public static boolean p(int i, int j, int index, char[] str, char[][] board) {
if (index == str.length) {
return true;
}
if (i >= board.length || j >= board[0].length || i < 0 || j < 0 ) {
return false;
}
if (board[i][j] == '0') {
return false;
}
char c = board[i][j];
board[i][j] = '0';
if (str[index] == c) {
boolean p1 = p(i + 1, j, index + 1, str, board);
if (p1) {
board[i][j] = c;
return true;
}
boolean p2 = p(i, j + 1, index + 1, str, board);
if (p2) {
board[i][j] = c;
return true;
}
boolean p3 = p(i - 1, j, index + 1, str, board);
if (p3) {
board[i][j] = c;
return true;
}
boolean p4 = p(i, j - 1, index + 1, str, board);
if (p4) {
board[i][j] = c;
return true;
}

}
board[i][j] = c;
return false;
}

}


## LeetCode 212. 单词搜索 II

for (int i = 0; i < board.length;i++) {
for (int j = 0; j < board[0].length;j++) {
int size = process(i,j, board, words);
if (size == words.size) {
return new ArrayList<>(words);
}
}
}


[apple, banana]


['a','p','p','l','e']
['a','x','y','b','a']
['b','a','n','a','n']


// 从board的i，j位置出发，
// 走过的路径保存在pre中，
// 收集到的单词表中的单词保存在ans中
// trie就是单词表建立的前缀树
int process(int i, int j, LinkedList<Character> pre, List<String> ans, char[][] board, Trie trie)


public static class Trie {
public Trie[] next;
public int pass;
public boolean end;
public Trie() {
// 由于只有26个小写字母，所以只需要准备26大小的数组即可。
next = new Trie[26];
// 遍历过的字符次数
pass = 0;
// 是否是一个字符串的结尾
end = false;
}
}


Set<String> set = new HashSet<>();
Trie trie = new Trie();
for (String word : words) {
if (!set.contains(word)){
buildTrie(trie,word);
}
}


private static void buildTrie(Trie trie, String word) {
char[] str = word.toCharArray();
for (char c : str) {
if (trie.next[c - 'a'] == null) {
trie.next[c - 'a'] = new Trie();
}
trie = trie.next[c - 'a'];
trie.pass++;
}
trie.end = true;
}


trie.next[x - 'a'] == null || trie.next[x - 'a'].pass == 0;


trie.end = true


public static int process(int i, int j, LinkedList<Character> pre, List<String> ans, char[][] board, Trie trie){
if (i >= board.length || i < 0 || j >= board[0].length || j < 0) {
return 0;
}
if (board[i][j] == '0') {
// 不走回头路
return 0;
}
if (trie.next[board[i][j] - 'a'] == null || trie.next[board[i][j] - 'a'].pass == 0) {
// 没有路可以走
return 0;
}
...
}


pre.addLast(c);
trie = trie.next[index];
int fix = 0;
if(trie.end) {
trie.end=false;
fix++;
}
// 这句表示：先标识一下当前位置为0字符，表示我已经走过了
board[i][j] = '0';
// 以下四行表示：
// 请去上，下，左，右四个方向帮我收集答案吧。
fix +=process(i+1,j,pre,ans,board,trie);
fix+=process(i,j+1,pre,ans,board,trie);
fix+=process(i-1,j,pre,ans,board,trie);
fix+=process(i,j-1,pre,ans,board,trie);
// 深度优先遍历的恢复现场操作。
board[i][j] = c;
pre.pollLast();
trie.pass-=fix;


private static String buildString(LinkedList<Character> pre) {
StringBuilder sb = new StringBuilder();
while (!preCopy.isEmpty()) {
Character c = preCopy.pollFirst();
sb.append(c);
}
return sb.toString();

}


public class LeetCode_0212_WordSearchII {
public static class Trie {
public Trie[] next;
public int pass;
public boolean end;
public Trie() {
next = new Trie[26];
pass = 0;
end = false;
}
}

public static List<String> findWords(char[][] board, String[] words){
Set<String> set = new HashSet<>();
Trie trie = new Trie();
for (String word : words) {
if (!set.contains(word)){
buildTrie(trie,word);
}
}
List<String> ans = new ArrayList<>();
for (int i = 0; i < board.length;i++) {
for (int j = 0; j < board[0].length;j++) {
int times = process(i,j,pre,ans,board,trie);
if (times == set.size()) {
return new ArrayList<>(set);
}
}
}
return ans;
}

public static int process(int i, int j, LinkedList<Character> pre, List<String> ans, char[][] board, Trie trie){
if (i >= board.length || i < 0 || j >= board[0].length || j < 0) {
return 0;
}
char c = board[i][j];
if (c == '0') {
// 不走回头路
return 0;
}
int index= c - 'a';
if (trie.next[index] == null || trie.next[index].pass == 0) {
// 没有路可以走
return 0;
}
trie = trie.next[index];

int fix = 0;
if(trie.end) {
trie.end=false;
fix++;
}
board[i][j] = '0';
fix +=process(i+1,j,pre,ans,board,trie);
fix+=process(i,j+1,pre,ans,board,trie);
fix+=process(i-1,j,pre,ans,board,trie);
fix+=process(i,j-1,pre,ans,board,trie);
board[i][j] = c;
pre.pollLast();
trie.pass-=fix;
return fix;
}

private static String buildString(LinkedList<Character> pre) {
StringBuilder sb = new StringBuilder();
while (!preCopy.isEmpty()) {
Character c = preCopy.pollFirst();
sb.append(c);
}
return sb.toString();

}

private static void buildTrie(Trie trie, String word) {
char[] str = word.toCharArray();
for (char c : str) {
if (trie.next[c - 'a'] == null) {
trie.next[c - 'a'] = new Trie();
}
trie = trie.next[c - 'a'];
trie.pass++;
}
trie.end = true;
}
}


## 更多

posted @ 2022-05-28 19:23  Grey Zeng  阅读(373)  评论(0编辑  收藏  举报