给定一个二维网格和一个单词,找出该单词是否存在于网格中。
单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
示例:
board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']
]
给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false
提示:
board 和 word 中只包含大写和小写英文字母。
1 <= board.length <= 200
1 <= board[i].length <= 200
1 <= word.length <= 10^3
思路:dfs回溯
1.对每一个单词,从board[0][0]开始遍历,分别向上下左右四个方向遍历,递归边界:当越过数组边界或者当前遍历到的字符与期望的word中的字符不同,则返回false,当已经成功遍历的字符个数等于word中的字符个数,则返回true。dfs中需要维持一个int w,表示已经成功遍历的字符。
2.空间复杂度优化,由于不能重复使用数组中的字符,所以在每次遍历一个字符之前,将该字符保存,同时对应项置为0,表示已经遍历,再遍历到该节点会退出。
AC代码:(C++)
class Solution {
public:
bool dfs(vector<vector<char>>& board, string& word, int i, int j, int w) {
if (board[i][j] != word[w]) return false;
if (w == word.length() - 1) return true;
char tmp = board[i][j];
board[i][j] = 0;
if ((i - 1 >= 0 && dfs(board, word, i - 1, j, w + 1)) ||
(j + 1 <= board[0].size() - 1 && dfs(board, word, i, j + 1, w + 1)) ||
(i + 1 <= board.size() - 1 && dfs(board, word, i + 1, j, w + 1)) ||
(j - 1 >= 0 && dfs(board, word, i, j - 1, w + 1)))
return true;
board[i][j] = tmp;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[0].size(); j++)
if (dfs(board, word, i, j, 0)) return true;
}
return false;
}
};