Skip to content

Commit 80b7da2

Browse files
committed
优化212
1 parent e92c92b commit 80b7da2

File tree

2 files changed

+61
-41
lines changed

2 files changed

+61
-41
lines changed

logbook/202503.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -966,7 +966,7 @@ endif::[]
966966
|{counter:codes2503}
967967
|{leetcode_base_url}/word-search-ii/[212. 单词搜索 II^]
968968
|{doc_base_url}/0212-word-search-ii.adoc[题解]
969-
|⭕️ 回溯,通过 43 / 65 个测试用例,后超时。
969+
|⭕️ 回溯,通过 43 / 65 个测试用例,后超时。利用前缀树+回溯,可以避免重复判断单词相同的前缀部分,可以节省大量的计算。
970970

971971
|===
972972

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,94 @@
11
package com.diguage.algo.leetcode;
22

3-
import java.util.*;
3+
import java.util.ArrayList;
4+
import java.util.HashSet;
5+
import java.util.List;
6+
import java.util.Set;
47

58
public class _0212_WordSearchIi {
69
// tag::answer[]
10+
711
/**
812
* 通过 43 / 65 个测试用例。超时!
913
*
1014
* @author D瓜哥 · https://www.diguage.com
1115
* @since 2025-06-12 22:53:03
1216
*/
17+
int[][] options = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
18+
1319
public List<String> findWords(char[][] board, String[] words) {
14-
Arrays.sort(words, String::compareTo);
15-
Map<Character, List<String>> charToWordMap = new HashMap<>();
16-
for (int i = 0; i < words.length; i++) {
17-
String word = words[i];
18-
char c = word.charAt(0);
19-
charToWordMap.computeIfAbsent(c, k -> new ArrayList<>()).add(word);
20+
Trie trie = new Trie();
21+
for (String word : words) {
22+
trie.insert(word);
2023
}
21-
Map<Character, List<int[]>> charToIndexMap = new HashMap<>();
24+
Set<String> result = new HashSet<>();
2225
for (int r = 0; r < board.length; r++) {
2326
for (int c = 0; c < board[r].length; c++) {
24-
char ac = board[r][c];
25-
if (charToWordMap.containsKey(ac)) {
26-
charToIndexMap.computeIfAbsent(ac, k -> new ArrayList<>())
27-
.add(new int[]{r, c});
28-
}
27+
dfs(board, r, c, trie, result);
2928
}
3029
}
31-
Set<String> result = new HashSet<>();
32-
charToIndexMap.forEach((k, v) -> {
33-
for (int[] idx : v) {
34-
List<String> aWords = charToWordMap.get(k);
35-
for (String aw : aWords) {
36-
dfs(board, idx[0], idx[1], aw, 0, new HashSet<>(), result);
37-
}
38-
}
39-
});
4030
return new ArrayList<>(result);
4131
}
4232

4333
private void dfs(char[][] board, int row, int col,
44-
String word, int idx, Set<List<Integer>> path,
45-
Set<String> result) {
46-
List<Integer> index = Arrays.asList(row, col);
47-
if (path.contains(index)) {
48-
return;
49-
}
50-
if (result.contains(word)) {
51-
return;
52-
}
53-
if (idx == word.length()) {
54-
result.add(word);
55-
return;
56-
}
34+
Trie trie, Set<String> result) {
5735
if (row < 0 || row >= board.length
5836
|| col < 0 || col >= board[0].length) {
5937
return;
6038
}
61-
if (board[row][col] != word.charAt(idx)) {
39+
char letter = board[row][col];
40+
if (!trie.containsLetter(letter)) {
6241
return;
6342
}
64-
path.add(index);
65-
int[][] options = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
43+
trie = trie.search(letter);
44+
if (trie.word != null) {
45+
result.add(trie.word);
46+
}
47+
board[row][col] = '#';
6648
for (int[] option : options) {
6749
int r = row + option[0];
6850
int c = col + option[1];
69-
dfs(board, r, c, word, idx + 1, path, result);
51+
dfs(board, r, c, trie, result);
52+
}
53+
board[row][col] = letter;
54+
}
55+
56+
public static class Trie {
57+
Trie[] children = new Trie[26];
58+
String word;
59+
60+
public void insert(String word) {
61+
Trie curr = this;
62+
for (int i = 0; i < word.length(); i++) {
63+
char c = word.charAt(i);
64+
if (curr.children[c - 'a'] == null) {
65+
curr.children[c - 'a'] = new Trie();
66+
}
67+
curr = curr.children[c - 'a'];
68+
}
69+
curr.word = word;
70+
}
71+
72+
public boolean containsLetter(char letter) {
73+
int idx = letter - 'a';
74+
if (idx < 0 || idx >= children.length) {
75+
return false;
76+
}
77+
return children[idx] != null;
78+
}
79+
80+
public Trie search(char letter) {
81+
return children[letter - 'a'];
7082
}
71-
path.remove(index);
7283
}
7384
// end::answer[]
85+
86+
public static void main(String[] args) {
87+
new _0212_WordSearchIi().findWords(new char[][]{
88+
{'o', 'a', 'b', 'n'},
89+
{'o', 't', 'a', 'e'},
90+
{'a', 'h', 'k', 'r'},
91+
{'a', 'f', 'l', 'v'}},
92+
new String[]{"oa", "oaa"});
93+
}
7494
}

0 commit comments

Comments
 (0)