leetcode#212 单词搜索II
题目:
给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words,找出所有同时在二维网格和字典中出现的单词。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例:
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
思路:
该算法的整个工作流程是直观的,包括在二维网格中的每个单元上循环和从单元开始的递归函数调用。这是算法的框架。
- 我们根据字典中的单词构建一个 Trie,稍后将用于匹配过程。
- 从每个单元格开始,如果字典中存在以单元格中的字母开头的单词,则我们开始回溯探索(即 backtracking(cell))。
- 在递归函数 backtracking(cell) 调用过程中,我们探索当前单元格周围的相邻单元格(即 neighborCell)以进行下一个递归调用 backtracking(neighborCell)。在每次调用时,我们都会检查到目前为止遍历的字母序列是否与字典中的任何单词匹配,这需要借助于我们在开始时构建的 Trie 数据结构。
代码
#include <bits/stdc++.h>
using namespace std;
struct node
{
bool is_word;
node *next[26];
node() : is_word(false), next() {}
};
class Solution
{
private:
node *root = new node();
vector<string> ans;
unordered_map<string, int> mp;
int dir[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int m, n;
public:
void init(vector<string> &words)
{
int num = words.size();
for (int i = 0; i < num; ++i)
{
node *now = root;
for (int j = 0; j < words[i].length(); ++j)
{
if (!now->next[words[i][j] - 'a'])
now->next[words[i][j] - 'a'] = new node();
now = now->next[words[i][j] - 'a'];
}
now->is_word = true;
}
}
void dfs(int x, int y, node *now, vector<vector<char>> &board, string res)
{
if (now->is_word && mp.find(res) == mp.end())
mp[res]++, ans.push_back(res);
for (int i = 0; i < 4; ++i)
{
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (xx >= 0 && xx < m && yy >= 0 && yy < n && board[xx][yy] != '.' && now->next[board[xx][yy] - 'a'])
{
char ch = board[xx][yy];
board[xx][yy] = '.';
res += ch;
dfs(xx, yy, now->next[ch - 'a'], board, res);
res.pop_back();
board[xx][yy] = ch;
}
}
}
vector<string> findWords(vector<vector<char>> &board, vector<string> &words)
{
m = board.size(), n = board[0].size();
init(words);
for (int i = 0; i < m; ++i)
for (int j = 0; j < n; ++j)
if (root->next[board[i][j] - 'a'] != NULL)
{
char ch = board[i][j];
string tmp = "";
tmp += board[i][j];
board[i][j] = '.';
dfs(i, j, root->next[ch - 'a'], board, tmp);
board[i][j] = ch;
}
return ans;
}
};