212. Word Search II

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: 
board = [
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]
words = ["oath","pea","eat","rain"]

Output: ["eat","oath"]

class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        List<String> list = new ArrayList();
        for(String word: words){
            if(exist(board, word)) list.add(word);
        }
        return list;
    }
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] visited = new boolean[m][n];
        for(int i = 0; i < m; i++){//Need traverse all possible i and j until get result
            for(int j = 0; j < n; j++){
                if(dfs(board,word,0,i,j,visited)) return true;
            }
        }
        return false;
    }
    public boolean dfs(char[][] board, String word, int index, int x, int y,boolean[][] visited){
        if(index==word.length()) return true;   //Means get what needed
        
        if(x<0||x==board.length||y<0||y==board[0].length) return false; //Means go beyond the boundary
         if(visited[x][y]) return false;    //Single element can only be accessed once in a dfs
        if(board[x][y] != word.charAt(index)) return false;
        visited[x][y]= true;    //Means current element never been accessed and existed in word.
            if(dfs(board, word, index+1, x+1,y,visited)||//right
               dfs(board, word, index+1, x-1,y,visited)||//left
               dfs(board, word, index+1, x,y+1,visited)||//up
               dfs(board, word, index+1, x,y-1,visited)){//down
                return true;
            }
               visited[x][y] = false;   //Release element xy to be accessed by next dfs
               return false;
    }
}

把wordsearch 1变成函数然后调用

 

class Solution {
    public List<String> findWords(char[][] board, String[] words) {
        List<String> res = new ArrayList<>();
        TrieNode root = buildTrie(words);
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                dfs (board, i, j, root, res);
            }
        }
        return res;
    }

    public void dfs(char[][] board, int i, int j, TrieNode p, List<String> res) {
        char c = board[i][j];
        if (c == '#' || p.next[c - 'a'] == null) return;
        p = p.next[c - 'a'];
        if (p.word != null) {   // found one
            res.add(p.word);
            p.word = null;     // de-duplicate word in words
        }

        board[i][j] = '#';//visited
        if (i > 0) dfs(board, i - 1, j ,p, res); 
        if (j > 0) dfs(board, i, j - 1, p, res);
        if (i < board.length - 1) dfs(board, i + 1, j, p, res); 
        if (j < board[0].length - 1) dfs(board, i, j + 1, p, res); 
        board[i][j] = c;//release board[i][j] after search failure
    }

    public TrieNode buildTrie(String[] words) {
        TrieNode root = new TrieNode();
        for (String w : words) {
            TrieNode p = root;
            for (char c : w.toCharArray()) {
                int i = c - 'a';
                if (p.next[i] == null) p.next[i] = new TrieNode();
                p = p.next[i];
           }
           p.word = w;
        }
        return root;
    }

    class TrieNode {
        TrieNode[] next = new TrieNode[26];
        String word;
    }
}

还可以用trie把words存成trie的形式,然后dfs,减少执行次数和时间

posted @ 2019-11-22 10:06  Schwifty  阅读(182)  评论(0编辑  收藏  举报