You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123 lines
3.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class26;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
// 本题测试链接 : https://leetcode.com/problems/word-search-ii/
public class Code02_WordSearchII {
public static class TrieNode {
public TrieNode[] nexts;
public int pass;
public boolean end;
public TrieNode() {
nexts = new TrieNode[26];
pass = 0;
end = false;
}
}
public static void fillWord(TrieNode head, String word) {
head.pass++;
char[] chs = word.toCharArray();
int index = 0;
TrieNode node = head;
for (int i = 0; i < chs.length; i++) {
index = chs[i] - 'a';
if (node.nexts[index] == null) {
node.nexts[index] = new TrieNode();
}
node = node.nexts[index];
node.pass++;
}
node.end = true;
}
public static String generatePath(LinkedList<Character> path) {
char[] str = new char[path.size()];
int index = 0;
for (Character cha : path) {
str[index++] = cha;
}
return String.valueOf(str);
}
public static List<String> findWords(char[][] board, String[] words) {
TrieNode head = new TrieNode(); // 前缀树最顶端的头
HashSet<String> set = new HashSet<>();
for (String word : words) {
if (!set.contains(word)) {
fillWord(head, word);
set.add(word);
}
}
// 答案
List<String> ans = new ArrayList<>();
// 沿途走过的字符收集起来存在path里
LinkedList<Character> path = new LinkedList<>();
for (int row = 0; row < board.length; row++) {
for (int col = 0; col < board[0].length; col++) {
// 枚举在board中的所有位置
// 每一个位置出发的情况下,答案都收集
process(board, row, col, path, head, ans);
}
}
return ans;
}
// 从board[row][col]位置的字符出发,
// 之前的路径上走过的字符记录在path里
// cur还没有登上有待检查能不能登上去的前缀树的节点
// 如果找到words中的某个str就记录在 res里
// 返回值从row,col 出发一共找到了多少个str
public static int process(
char[][] board, int row, int col,
LinkedList<Character> path, TrieNode cur,
List<String> res) {
char cha = board[row][col];
if (cha == 0) { // 这个row col位置是之前走过的位置
return 0;
}
// (row,col) 不是回头路 cha 有效
int index = cha - 'a';
// 如果没路,或者这条路上最终的字符串之前加入过结果里
if (cur.nexts[index] == null || cur.nexts[index].pass == 0) {
return 0;
}
// 没有走回头路且能登上去
cur = cur.nexts[index];
path.addLast(cha);// 当前位置的字符加到路径里去
int fix = 0; // 从row和col位置出发后续一共搞定了多少答案
// 当我来到row col位置如果决定不往后走了。是不是已经搞定了某个字符串了
if (cur.end) {
res.add(generatePath(path));
cur.end = false;
fix++;
}
// 往上、下、左、右,四个方向尝试
board[row][col] = 0;
if (row > 0) {
fix += process(board, row - 1, col, path, cur, res);
}
if (row < board.length - 1) {
fix += process(board, row + 1, col, path, cur, res);
}
if (col > 0) {
fix += process(board, row, col - 1, path, cur, res);
}
if (col < board[0].length - 1) {
fix += process(board, row, col + 1, path, cur, res);
}
board[row][col] = cha;
path.pollLast();
cur.pass -= fix;
return fix;
}
}