LeetCode 212. Word Search II

原题链接在这里:https://leetcode.com/problems/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.

For example,
Given words = ["oath","pea","eat","rain"] and board =

[
  ['o','a','a','n'],
  ['e','t','a','e'],
  ['i','h','k','r'],
  ['i','f','l','v']
]

Return ["eat","oath"].

Note:
You may assume that all inputs are consist of lowercase letters a-z.

题解:

Word Search的进阶版题目,同时可以利用Implement Trie (Prefix Tree).

生成Trie树,把所有的词都insert进去.

然后从board上的每一个char开始dfs查找.

终止条件有两个, 一个 i 和 j 出界,或者board[i][j]已经用过了. 另一个是with board[i][j], current TrieNode doesn't have any nexts node, which means starting with it. 

search 更新过的item, 若是有就加到res中, 并且继续,这里不能return, 因为有可能有 "aabc" "aabcb"两个词同时存在的情况,只检查了"aabc"就return会漏掉"aabcb".

标记当前used为true, 然后board四个方向都做recursion. used再改回来.

Note: 如果board 是[a a], words 只有一个[a], 此时小心重复加, thus we could reset TrieNode.val back to null after adding it to res.

Time Complexity: O(k*l + m*n*3^l). k*l是buildTrie用时间. m*n是外部循环, 3^l是recursion + backtracking的时间, since at most we have 3 directions to go.

m = board.length, n = board[0].length, k = words.length, l 是 word的平均长度.

Space: O(k*l + l). k*l是Trie数的大小. 用了l层stack.

AC Java:

 1 class Solution {
 2     public List<String> findWords(char[][] board, String[] words) {
 3         List<String> res = new ArrayList<>();
 4         if(board == null || board.length == 0 || board[0].length == 0 || words == null || words.length == 0){
 5             return res;
 6         }
 7         
 8         TrieNode root = buildTrie(words);
 9         
10         int m = board.length;
11         int n = board[0].length;
12         boolean [][] used = new boolean[m][n];
13         for(int i = 0; i<m; i++){
14             for(int j = 0; j<n; j++){
15                 dfs(board, i, j, m, n, used, root, res);
16             }
17         }
18         
19         return res;
20     }
21     
22     private void dfs(char [][] board, int i, int j, int m, int n, boolean[][] used, TrieNode p, List<String> res){
23         if(i < 0 || i >= m || j < 0 || j >= n || used[i][j]){
24             return;
25         }
26         
27         if(p.nexts[board[i][j] - 'a'] == null){
28             return;
29         }
30         
31         p = p.nexts[board[i][j] - 'a'];
32         if(p.val != null){
33             res.add(p.val);
34             p.val = null;
35         }
36         
37         used[i][j] = true;
38         dfs(board, i + 1, j, m, n, used, p, res);
39         dfs(board, i - 1, j, m, n, used, p, res);
40         dfs(board, i, j + 1, m, n, used, p, res);
41         dfs(board, i, j - 1, m, n, used, p, res);
42         used[i][j] = false;
43     }
44     
45     private TrieNode buildTrie(String [] words){
46         TrieNode root = new TrieNode();
47         for(String w : words){
48             TrieNode p = root;
49             for(char c : w.toCharArray()){
50                 if(p.nexts[c - 'a'] == null){
51                     p.nexts[c - 'a'] = new TrieNode();
52                 }
53                 
54                 p = p.nexts[c - 'a'];
55             }
56             
57             p.val = w;
58         }
59         
60         return root;
61     }
62 }
63 
64 class TrieNode{
65     String val;
66     TrieNode [] nexts;
67     
68     public TrieNode(){
69         nexts = new TrieNode[26];
70     }
71 }

 

posted @ 2015-11-07 09:11  Dylan_Java_NYC  阅读(1440)  评论(0编辑  收藏  举报