[LeetCode] 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.

click to show hint.

You would need to optimize your backtracking to pass the larger test. Could you stop backtracking earlier?

If the current candidate does not exist in all words' prefix, you could stop backtracking immediately. What kind of data structure could answer such query efficiently? Does a hash table work? Why or why not? How about a Trie? If you would like to learn how to implement a basic trie, please work on this problem: Implement Trie (Prefix Tree) first.

 又一道新題,最近LeetCode出現新題的速度略快啊。剛看到題目想到之前有一道Word Search,所以馬上想到暴力搜索每一個單詞,但是很不幸跟預想的一樣超時了,看了一下hint,提到了字典樹。所以先用所給的單詞來構建字典樹,然后在dfs搜索字典樹中的單詞,這樣就避免了大量的重復比較。另外如果搜索的路徑已經不是字典樹是的前綴了就可以直接剪枝返回了。下面是AC代碼。因為要避免重復,我先用了一個set存結果,然后再轉存到result中。

 1 class Solution {
 2 public:
 3     struct TriNode {
 4         TriNode *ch[26];
 5         bool isWord;
 6         TriNode() : isWord(false) {
 7             for (auto &a : ch) a = NULL;
 8         }
 9     } *root;
10     
11     void insert(string word) {
12         TriNode *p = root;
13         for (auto &a : word) {
14             int i = a - 'a';
15             if (p->ch[i] == NULL) p->ch[i] = new TriNode();
16             p = p->ch[i];
17         }
18         p->isWord = true;
19     }
20     
21     bool isPrefix(string word) {
22         TriNode *p = root;
23         for (auto &a : word) {
24             int i = a - 'a';
25             if (p->ch[i] == NULL) return false;
26             p = p->ch[i];
27         }
28         return true;
29     }
30     
31     bool isWord(string word) {
32         TriNode *p = root;
33         for (auto &a : word) {
34             int i = a - 'a';
35             if (p->ch[i] == NULL) return false;
36             p = p->ch[i];
37         }
38         return p->isWord;
39     }
40     
41     Solution() {
42         root = new TriNode();
43     }
44     
45     bool isValid(vector<vector<char>> &board, vector<vector<bool>> &visit, int x, int y) {
46         int m = board.size(), n = board[0].size();
47         if (x < 0 || x >= m || y < 0 || y >= n || visit[x][y]) return false;
48         return true;
49     }
50     
51     bool dfs(vector<vector<char>> &board, vector<vector<bool>> &visit, set<string> &st, string &s, int x, int y) {
52         int dx[4] = {1, 0, -1, 0};
53         int dy[4] = {0, 1, 0, -1};
54         visit[x][y] = true;
55         int xx, yy;
56         for (int i = 0; i < 4; ++i) {
57             xx = x + dx[i]; yy = y + dy[i];
58             if (isValid(board, visit, xx, yy)) {
59                 s.push_back(board[xx][yy]);
60                 if (isWord(s)) st.insert(s);
61                 if (isPrefix(s)) dfs(board, visit, st, s, xx, yy);
62                 s.pop_back();
63             }
64         }
65         visit[x][y] = false;
66     }
67     
68     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
69         vector<string> res;
70         if (board.empty() || board[0].empty() || words.empty()) return res;
71         for (auto &word : words) insert(word);
72         int m = board.size(), n = board[0].size();
73         vector<vector<bool>> visit(m, vector<bool>(n, false));
74         string s;
75         set<string> st;
76         for (int i = 0; i < m; ++i) {
77             for (int j = 0; j < n; ++j) {
78                 s.push_back(board[i][j]);
79                 if (isWord(s)) st.insert(s);
80                 if (isPrefix(s)) dfs(board, visit, st, s, i, j);
81                 s.pop_back();
82             }
83         }
84         for (auto &word : st) res.push_back(word);
85         return res;
86     }
87 };

 下面是超時算法:

 1 class Solution {
 2 public:
 3     bool isValid(vector<vector<char>> &board, vector<vector<bool>> &visit, int x, int y) {
 4         int m = board.size(), n = board[0].size();
 5         if (x < 0 || x >= m || y < 0 || y >= n || visit[x][y]) return false;
 6         return true;
 7     }
 8     
 9     bool dfs(vector<vector<char>> &board, vector<vector<bool>> &visit, string word, int idx, int x, int y) {
10         if (idx == word.length()) return true;
11         int dx[4] = {1, 0, -1, 0};
12         int dy[4] = {0, 1, 0, -1};
13         visit[x][y] = true;
14         int xx, yy;
15         for (int i = 0; i < 4; ++i) {
16             xx = x + dx[i]; yy = y + dy[i];
17             if (isValid(board, visit, xx, yy) && board[xx][yy] == word[idx] && dfs(board, visit, word, idx + 1, xx, yy)) {
18                 return true;
19             }
20         }
21         visit[x][y] = false;
22         return false;
23     }
24     
25     bool exist(vector<vector<char>>& board, string word) {
26         if (board.empty() || board[0].empty() || word.empty()) return false;
27         int m = board.size(), n = board[0].size();
28         vector<vector<bool>> visit(m, vector<bool>(n, false));
29         for (int i = 0; i < m; ++i) {
30             for (int j = 0; j < n; ++j) {
31                 if (board[i][j] == word[0] && dfs(board, visit, word, 1, i, j)) return true;
32             }
33         }
34         return false;
35     }
36     
37     vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
38         vector<string> res;
39         if (words.empty()) return res;
40         sort(words.begin(), words.end());
41         if (exist(board, words[0])) res.push_back(words[0]);
42         for (int i = 1; i < words.size(); ++i) {
43             if (words[i] != words[i-1] && exist(board, words[i])) res.push_back(words[i]);
44         }
45         return res;
46     }
47 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM