[leetcode] 212. 单词搜索 II(Java)
这leetcode的评判机绝对有问题!!同样的代码提交,有时却超时!害得我至少浪费两个小时来寻找更优的答案= =,其实第一次写完的代码就可以过了,靠!!!第207位做出来的
趁热,我把79. 单词搜索也做了一下
与79题完全,无非是从一个word变成了多个word,我们多次调用79题的代码即可
这样的话,我们能过掉除了最后一组数组外的其它所有数据。最后一组数据超时。
那么我们就得考虑如何优化了,优化方向也就是题目中提示所说的:
- 提前停止回溯。这个在79题的代码中已经做到了,找到了后直接结束搜索就好了,不必再继续回溯。
- 如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。我举个例子:如果abc不存在于网格中,那么以abc为子串的所有word,肯定也不存在于网格中。我们将words排序,凡是不存在于网格中的word,将其标记起来,即为wordNotExist,后面再遍历word时,先看其包不包含wordNotExist,如果包含,则不用搜了。代码如下:
boolean notExistFlag = false;
for (int j = 1; j < word.length(); j++) {
if (notExistWords.containsKey(word.substring(0, j + 1))) {
notExistFlag = true;
break;
}
}
if (notExistFlag) continue;
全部代码
class Solution {
static int[][] d = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
static Map<String, Boolean> notExistWords = new HashMap<>();
public List<String> findWords(char[][] board, String[] words) {
List<String> ans = new ArrayList<>();
Arrays.sort(words);
notExistWords.clear();
for (int i = 0; i < words.length; i++) {
String word = words[i];
// 去重
if (i > 0 && word.equals(words[i - 1])) continue;
// 优化
boolean notExistFlag = false;
for (int j = 1; j < word.length(); j++) {
if (notExistWords.containsKey(word.substring(0, j + 1))) {
notExistFlag = true;
break;
}
}
if (notExistFlag) continue;
if (exist(board, word)) {
ans.add(word);
} else {
notExistWords.put(word, false);
}
}
return ans;
}
public boolean exist(char[][] board, String word) {
int m = board.length;
if (m == 0) return false;
int n = board[0].length;
if (n == 0) return false;
if (word.equals("")) return true;
boolean[][] f = new boolean[m][n];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (word.charAt(0) == board[i][j]) {
f[i][j] = true;
boolean flag = dfs(i, j, 1, board, word, m, n, f);
if (flag) return true;
f[i][j] = false;
}
}
}
return false;
}
private boolean dfs(int i, int j, int k, char[][] board, String word, int m, int n, boolean[][] f) {
if (k == word.length()) {
return true;
}
for (int l = 0; l < 4; l++) {
if (i + d[l][0] < m && j + d[l][1] < n && i + d[l][0] >= 0 && j + d[l][1] >= 0 && board[i + d[l][0]][j + d[l][1]] == word.charAt(k) && !f[i + d[l][0]][j + d[l][1]]) {
f[i + d[l][0]][j + d[l][1]] = true;
boolean flag = dfs(i + d[l][0], j + d[l][1], k + 1, board, word, m, n, f);
if (flag) return true;
f[i + d[l][0]][j + d[l][1]] = false;
}
}
return false;
}
}