Question 212 – Word Search II
给定一个字符表和一个string集,返回能在字母表中找到的该string集中的string集。一个string能在字符表中找到表示,在字符表中存在一些连续相邻的字符组成该string。
算法
- 使用上一篇博客Word search的方法
对每一个string分别去在字符表中查找,若能找到则将该string添加到返回集中。
对于一个特定的string在字符表中查找时:以每一个字符为起点,做一遍DFS,成功则返回true。
具体过程见代码。 - 使用前缀树Trie
Code
1.
class Solution {
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
int count=0;
vector<string> canfind;
map<string, int> m;
for(string str: words){
int flag = 0;
if(m.count(str)==1) continue;
else m.insert(pair<string, int>(str, count++));
for (int i = 0; i < (int)board.size(); i++){
if(flag) break;
for (int j = 0; j < (int)board[0].size(); j++){
if(dfsfind(board, i, j, str.c_str(), 0)){
canfind.push_back(str);
flag = 1;
break;
}
}
}
}
return canfind;
}
bool dfsfind(vector<vector<char>> &board, int row, int col, const char *ch, int nowpos){
if(row<0 || row>=(int)board.size() || col<0 || col>=(int)board[0].size() || board[row][col]!=ch[nowpos]) return false;
if(ch[nowpos+1]=='\0') return true;
char temp = board[row][col];
board[row][col] = '\0';
if(dfsfind(board, row, col - 1, ch, nowpos + 1) ||
dfsfind(board, row, col + 1, ch, nowpos + 1) ||
dfsfind(board, row - 1, col, ch, nowpos + 1) ||
dfsfind(board, row + 1, col, ch, nowpos + 1)){
board[row][col] = temp;
return true;
}
board[row][col] = temp;
return false;
}
};
2.
class Solution{
private:
class Trie{
public:
Trie *next[26];
bool isleaf;
int indexinwords;
Trie(){
fill_n(next, 26, nullptr);
isleaf = false;
indexinwords = -1;
}
~Trie(){
for (int i = 0; i < 26; i++)
delete next[i];
}
};
void insertTotrie(Trie* root, vector<string>& words, int index){
for (int i = 0; i < (int)words[index].size(); i++){
if(root->next[words[index][i]-'a']==nullptr)
root->next[words[index][i] - 'a'] = new Trie();
root = root->next[words[index][i] - 'a'];
}
root->isleaf = true;
root->indexinwords = index;
}
Trie* buildTrie(vector<string>& words){
Trie *root=new Trie();
for (int i = 0; i < (int)words.size(); i++){
insertTotrie(root, words, i);
}
return root;
}
void dfs(vector<vector<char>> &board, int row, int col, Trie *root, vector<string> &result, vector<string> &words){
if(row<0||row>=(int)board.size()||col<0||col>=(int)board[0].size()||board[row][col]=='\0'||
root->next[board[row][col]-'a']==nullptr) return;
if(root->next[board[row][col]-'a']->isleaf==true){
result.push_back(words[root->next[board[row][col]-'a']->indexinwords]);
root->next[board[row][col]-'a']->isleaf = false;
}
root = root->next[board[row][col] - 'a'];
char temp = board[row][col];
board[row][col] = '\0';
dfs(board, row, col - 1, root, result, words);
dfs(board, row, col + 1, root, result, words);
dfs(board, row - 1, col, root, result, words);
dfs(board, row + 1, col, root, result, words);
board[row][col] = temp;
return;
}
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words){
Trie *root = buildTrie(words);
vector<string> result;
for (int i = 0; i < (int)board.size(); i++){
for (int j = 0; j < (int)board[0].size(); j++){
dfs(board, i, j, root, result, words);
}
}
return result;
}
};