Leetcode 212. Word Search II

题目:node

Given a 2D board and a list of words from the dictionary, find all
words in the board.

Each word must be constructed from letters of sequentially adjacent
cell, where "adjacent" cells are those horizontally or vertically
neighboring. The same letter cell may not be used more than once in a
word.
Example:数组

Input: words = ["oath","pea","eat","rain"] and board =
[
['o','a','a','n'],
['e','t','a','e'],
['i','h','k','r'],
['i','f','l','v']
]ui

Output: ["eat","oath"] Note: You may assume that all inputs are
consist of lowercase letters a-z.code

这道题是79题word search的follow up,若是按照那道题的作法咱们在二维数组中寻找每个单词那么必定会超时,由于每一个单词都要搜索一次会产生不少重复搜索,因此咱们想到的是从头至尾遍历二维数组,在遍历过程当中dfs,那么在这个过程当中必定把全部可能组成的单词都遍历了一遍,因此咱们想到能够用一个hashset来存储须要搜索的单词,而后在dfs过程当中把每一个产生的单词在hashset中寻找。
代码以下:rem

class Solution {
    List<String> res = new ArrayList<>();
    HashSet<String> set = new HashSet<>();
    boolean[][] visited;
    public List<String> findWords(char[][] board, String[] words) {
        visited = new boolean[board.length][board[0].length];
        for (String word : words)   
            set.add(word);
        for (int i = 0; i < board.length; i ++) {
            for (int j = 0; j < board[0].length; j ++) {
                dfs(board, "", i, j);
            }
        }
        return res;
    }
    public void dfs(char[][] board, String cur, int x, int y) {
        if (x == board.length || x < 0 || y == board[0].length || y < 0 || visited[x][y])
            return;
        char c = board[x][y];
        if (set.contains(cur+c)) {
            res.add(cur+c);
            set.remove(cur+c);
        }
        visited[x][y] = true;
        dfs(board, cur+c, x+1, y);
        dfs(board, cur+c, x-1, y);
        dfs(board, cur+c, x, y+1);
        dfs(board, cur+c, x, y-1);
        visited[x][y] = false;
    }
}

但不幸的是这种方法仍是会超时,因此咱们想可否有种方法能让咱们提早结束backtrack呢,若是在全部单词中都没有这个前缀咱们就能够提早结束backtarcking。所以想到能够用Trie来实现,代码以下:input

class Solution {
    class TrieNode {
        TrieNode[] next = new TrieNode[26];
        String word;
        public TrieNode() {}
    }
    TrieNode buildTrie(String[] words) {
        TrieNode root = new TrieNode();
        for (String word : words) {
            TrieNode p = root;
            for (char c : word.toCharArray()) {
                if (p.next[c-'a'] == null)
                    p.next[c-'a'] = new TrieNode();
                p = p.next[c-'a'];
            }
            p.word = word;
        }
        return root;
    }
    List<String> res = new ArrayList<>();
    boolean[][] visited;
    public List<String> findWords(char[][] board, String[] words) {
        visited = new boolean[board.length][board[0].length];
        TrieNode root = buildTrie(words);
        for (int i = 0; i < board.length; i ++) {
            for (int j = 0; j < board[0].length; j ++) {
                if (root.next[board[i][j]-'a'] == null) continue;
                dfs(board, root, i, j);
            }
        }
        return res;
    }
    public void dfs(char[][] board, TrieNode node, int x, int y) {
        if (x == board.length || x < 0 || y == board[0].length || y < 0 || visited[x][y])
            return;
        char c = board[x][y];
        if (node.next[c-'a'] == null)   return;
        if (node.next[c-'a'].word != null) {
            res.add(node.next[c-'a'].word);
            //若是找到了这个单词就把它设成null,避免重复的结果
            node.next[c-'a'].word = null;
        }
        visited[x][y] = true;
        dfs(board, node.next[c-'a'], x+1, y);
        dfs(board, node.next[c-'a'], x-1, y);
        dfs(board, node.next[c-'a'], x, y+1);
        dfs(board, node.next[c-'a'], x, y-1);
        visited[x][y] = false;
    }
}
相关文章
相关标签/搜索