持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第10天,点击查看活动详情
212. 单词搜索II
来源:力扣(LeetCode)
给定一个 m x n 二维字符网格 board和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。
单词必须按照字母顺序,通过 相邻的单元格 内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母在一个单词中不允许被重复使用。
示例 1:
输入:board = [["o","a","a","n"],["e","t","a","e"],["i","h","k","r"],["i","f","l","v"]], words = ["oath","pea","eat","rain"]
输出:["eat","oath"]
示例 2:
输入:board = [["a","b"],["c","d"]], words = ["abcb"]
输出:[]
提示:
- m == board.length
- n == board[i].length
- 1 <= m, n <= 12
- board[i][j] 是一个小写英文字母
- 1 <= words.length <=
- 1 <= words[i].length <= 10
- words[i] 由小写英文字母组成
- words 中的所有字符串互不相同
解法
- 字典树+DFS:
- 首先对words使用字典树进行保存,方便后续的查找
- 之后对每个格子进行dfs搜索,看看每个格子位置的字符是否在字典树中,如果在的话先确定是否能成为单词,如果不是单词继续朝着四个方向遍历下去,这里注意同一个单元格内字母不能重复使用,因此遍历每个字符时候先改变其状态,遍历完成之后重置为原来的字符;
代码实现
字典树+DFS
python实现
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
tries = dict()
for word in words:
t = tries
for ch in word:
if ch not in t:
t[ch] = dict()
t = t[ch]
t['end'] = 1
res = []
m = len(board)
n = len(board[0])
def dfs(i, j, s, tries):
ch = board[i][j]
if ch not in tries:
return
tries = tries[ch]
if 'end' in tries and tries['end'] == 1:
res.append(s+ch)
tries['end'] = 0
board[i][j] = '#'
for dx, dy in [(0, 1), (0, -1), (-1, 0), (1, 0)]:
ni = i + dx
nj = j + dy
if 0 <= ni < m and 0 <= nj < n and board[ni][nj] != '#':
dfs(ni, nj, s+ch, tries)
board[i][j] = ch
for i in range(m):
for j in range(n):
dfs(i, j, '', tries)
return res
c++实现
struct Trie {
Trie* children[26] = {nullptr};
string word = "";
};
class Solution {
private:
vector<string> ans;
vector<int> dir = {-1, 0, 1, 0, -1};
Trie* initializeTree(vector<string>& words) {
Trie* t = new Trie();
Trie* cur;
for (auto word: words) {
cur = t;
for (auto ch: word) {
if (cur->children[ch-'a'] == nullptr)
cur->children[ch-'a'] = new Trie();
cur = cur->children[ch-'a'];
}
cur->word = word;
}
return t;
}
void dfs(vector<vector<char>>& board, Trie* t, int i, int j) {
char tmp = board[i][j];
if (tmp == '*' || t->children[tmp-'a'] == nullptr) return ;
t = t->children[tmp-'a'];
if (t->word != ""){
ans.emplace_back(t->word);
t->word = "";
}
board[i][j] = '*';
for (int k=0; k<4; k++) {
int r = i+dir[k], c = j+dir[k+1];
if (r >= 0 && r < board.size() && c >= 0 && c < board[0].size())
dfs(board, t, r, c);
}
board[i][j] = tmp;
return ;
}
public:
vector<string> findWords(vector<vector<char>>& board, vector<string>& words) {
Trie* t = initializeTree(words);
for (int i=0; i<board.size(); i++) {
for(int j=0; j<board[0].size(); j++) {
dfs(board, t, i, j);
}
}
return ans;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度:
- 时间空间复杂度存疑