题目内容
题目链接: https://leetcode-cn.com/problems/word-search-ii
Given an m x n board of characters and a list of strings words, return all words on the board.
Each word must be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.
Input: board = [[“o”,“a”,“a”,“n”],[“e”,“t”,“a”,“e”],[“i”,“h”,“k”,“r”],[“i”,“f”,“l”,“v”]], words = [“oath”,“pea”,“eat”,“rain”]
Output: [“eat”,“oath”]
分析
看到这样的字符串查找、搜索,能想到字典树Trie
,这道题目的数据规模不大,所以可以先将字符串words
插入到字典树中,然后暴力DFS
搜索整个board
。
代码
class Solution {
public:
int son[100000][26] = {0}, cnt[100000] = {0}, idx = 0;
int dis[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
vector<string> res;
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
// 将word插入到字典树中
for (auto word: words) insert(word);
for (int i = 0; i < board.size(); i ++)
for (int j = 0; j < board[0].size(); j ++)
dfs(0, i, j, board, "");
return res;
}
// 全文背诵y总的模板,
void insert(string str) {
int p = 0;
for (auto c: str)
{
int o = c - 'a';
if(!son[p][o]) son[p][o] = ++ idx;
p = son[p][o];
}
cnt[p] ++;
}
// 暴力搜索
void dfs(int p, int i, int j, vector<vector<char>>& b, string s) {
// 越界直接return
if (i < 0 || j < 0 || i >= b.size() || j >= b[0].size()) return ;
char c = b[i][j];
int o = c - 'a';// 计算偏移量
// 如果该点已经走过了,或者该Trie中没有该点,直接return
if (c == '1' || !son[p][o])return ;
// 运行到这里,说明Trie中含有该点(即son[p][o]!=0)
p = son[p][o];
// 若cnt不等0,则说明Tire中有s+c这个字符串,加入到res之后,将cnt置为0即可。
if (cnt[p]) res.push_back(s + c), cnt[p] = 0;
// 该点已经被用过了,所以标记一下
b[i][j] = '1';
for (int k = 0; k < 4; k ++)
// 4个方向dfs
dfs(p, i + dis[k][0], j + dis[k][1], b, s + c);
// 恢复该点,便于下一次dfs
b[i][j] = c;
}
};