给出一个由小写字母组成的矩阵和一个字典。找出所有同时在字典和矩阵中出现的单词。一个单词可以从矩阵中的任意位置开始,可以向左/右/上/下四个相邻方向移动。
解法:
建立字典树存储所有要找的单词,在一个单词的最后一个字符节点上存储该单词指针
沿着字典树节点在矩阵中搜索,碰到单词的最后一个字符节点就表示找到该单词,记录到结果中
class DicNode {
public:
DicNode* children[256];
string* str;
DicNode() {
for(int i = 0; i < 256; ++i) {
children[i] = NULL;
}
str = NULL;
}
void put(string& s, int pos = 0) {
if(pos == s.size()) {
str = &s;
return;
}
char c = s[pos];
if(children[c] == NULL) {
children[c] = new DicNode();
}
children[c]->put(s, pos + 1);
}
};
class Solution {
public:
/**
* @param board: A list of lists of character
* @param words: A list of string
* @return: A list of string
*/
vector<string> wordSearchII(vector<vector<char> > &board, vector<string> &words) {
// write your code here
vector<string> r;
if(board.size() == 0) return r;
DicNode* node = new DicNode();
for(int i = 0; i < words.size(); ++i) {
node->put(words[i]);
}
for(int i = 0; i < board.size(); ++i) {
for(int j = 0; j < board[i].size(); ++j) {
sub(i, j, node, board, r);
}
}
return r;
}
void sub(int px, int py, DicNode* node, vector<vector<char> > &board, vector<string>& r) {
if(px < 0 || px >= board.size() || py < 0 || py >= board[0].size()) return;
char c = board[px][py];
DicNode* cur = node->children[c];
if(cur != NULL) {
if(cur->str != NULL) {
r.push_back(*(cur->str));
cur->str = NULL;
}
board[px][py] = '#';
sub(px + 1, py, cur, board, r);
sub(px - 1, py, cur, board, r);
sub(px, py + 1, cur, board, r);
sub(px, py - 1, cur, board, r);
board[px][py] = c;
}
}
};