LeetCode/solutions/212. Word Search II.md
2020-03-21 00:48:30 +08:00

89 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# [212. Word Search II](https://leetcode.com/problems/word-search-ii/)
# 思路
这题是[79. Word Search](https://leetcode.com/problems/word-search/)的升级版79题是判断某个单词是否存在与board中而此题是给了一堆单词让返回所有存在的单词。
亲测按照79那样直接搜索是会超时的不然就不是hard题了那我们只好考虑更加高效的方法。由于是在一个单词集合中查询那么我们考虑用字典树Trie所以我们可以直接把[208题](208.%20Implement%20Trie%20(Prefix%20Tree).md)的字典树实现拿过来用,不过只用到了`insert`操作。
字典树建好后我们就可以DFS了一旦遇到了字典树某个节点`is_last_letter == true`就说明找到了将此时对应的单词加入结果数组中为了避免下一次DFS时重复找到这个单词我们应该将这里的`is_last_letter`设为false表示单词集里面没有这个单词了。
代码中使用了一个小技巧,类似[79题思路二](79.%20Word%20Search.md)那样我们使用DFS时不另开visited数组而是用原数组board来记录某个元素是否被访问过若被访问过就将board对应位置改成字符`*`注意DFS结束前要改回来。
# C++
``` C++
struct TrieNode{
bool is_last_letter; // 是否是某个单词的结尾
char letter;
vector<TrieNode *>next; // 孩子们
TrieNode(char cc): is_last_letter(false), letter(cc),
next(vector<TrieNode *>(26, NULL)){}
};
class Trie {
private:
TrieNode *root;
public:
Trie() {
root = new TrieNode('\0'); // 根节点不包含字符
root -> is_last_letter = true;
}
TrieNode* getRoot(){return root;}
/** Inserts a word into the trie. */
void insert(string word) {
if(word.empty()) return;
TrieNode *p = root;
for(int i = 0; i < word.size(); i++){
int idx = word[i] - 'a';
if(NULL == (p -> next)[idx]) // 没找到, 插入即可
(p -> next)[idx] = new TrieNode(word[i]);
p = (p -> next)[idx];
}
p -> is_last_letter = true;
}
};
class Solution {
private:
int row, col;
vector<string>res;
const vector<int>dx = {0,0,1,-1}, dy = {1,-1,0,0};
void DFS(vector<vector<char>>& board,
vector<TrieNode *>&nodes, int i, int j, string word){
if(i < 0 || i >= row || j < 0 || j >= col || board[i][j] == '*') return;
TrieNode *node = nodes[board[i][j] - 'a'];
if(!node) return;
word.append(1, board[i][j]);
char tmp = board[i][j]; board[i][j] = '*';
if(node -> is_last_letter) {
res.push_back(word);
// 避免下一次DFS时重复找到这个单词
node -> is_last_letter = false;
}
for(int k = 0; k < 4; k++)
DFS(board, node -> next, i+dx[k], j+dy[k], word);
board[i][j] = tmp;
}
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
row = board.size();
if(!row || words.empty()) return res;
col = board[0].size();
Trie tree;
for(string word: words) tree.insert(word);
for(int i = 0; i < row; i++)
for(int j = 0; j < col; j++)
DFS(board, tree.getRoot() -> next, i, j, "");
return res;
}
};
```