[leetcode] 212. 单词搜索 II(Java)

212. 单词搜索 II

这leetcode的评判机绝对有问题!!同样的代码提交,有时却超时!害得我至少浪费两个小时来寻找更优的答案= =,其实第一次写完的代码就可以过了,靠!!!第207位做出来的

趁热,我把79. 单词搜索也做了一下

与79题完全,无非是从一个word变成了多个word,我们多次调用79题的代码即可

这样的话,我们能过掉除了最后一组数组外的其它所有数据。最后一组数据超时。

那么我们就得考虑如何优化了,优化方向也就是题目中提示所说的:

  1. 提前停止回溯。这个在79题的代码中已经做到了,找到了后直接结束搜索就好了,不必再继续回溯。
  2. 如果当前单词不存在于所有单词的前缀中,则可以立即停止回溯。我举个例子:如果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;
    }
}

posted @ 2018-07-30 16:11  ACBingo  阅读(278)  评论(0编辑  收藏  举报