我正在解决单词搜索 https://leetcode.com/problems/word-search/description/LeetCode.com 上的问题:
给定一个 2D 板和一个单词,查找该单词是否存在于网格中。
该单词可以由顺序相邻单元格的字母构成,其中“相邻”单元格是水平或垂直相邻的单元格。同一字母单元不得使用多次。
我根据网上帮助写的解决方案如下:
class Solution {
public:
//compare this with Max Area of Island:
//they 'look' similar, but this one uses a backtracking approach since we retract when we don't find a solution
//In case of Max Area Of Island, we are not 'coming back' - technically we do come back due to recursion, but we don't track
//that since we don't acutally intend to do anything - we are just counting the 1s.
bool exist(vector<vector<char>>& board, string& word) {
if(board.empty()) return false;
for(int i=0; i<board.size(); i++) {
for(int j=0; j<board[0].size(); j++) {
//if(word[0] == board[i][j])
if(existUtil(board, word, i, j, 0)) //matching the word[i][j] with 0th character of word
return true;
}
}
return false;
}
bool existUtil(vector<vector<char>>& board, string& word, int i, int j, int match) {
if(match==word.size()) return true;
if(i<0 || i>=board.size() || j<0 || j>=board[0].size()) return false;
if(board[i][j]!=word[match]) return false;
board[i][j] = '*';
bool ans = existUtil(board, word, i+1, j, match+1) || //[i+1,j]
existUtil(board, word, i-1, j, match+1) || // [i,j+1]
existUtil(board, word, i, j+1, match+1) || // [i-1,j]
existUtil(board, word, i, j-1, match+1); // [i,j-1]
board[i][j] = word[match];
return ans;
}
};
我的问题很简单 - 为什么我们使用回溯方法而不仅仅是传统的 DFS?与我们所做的非常相似,我们可以从每个字符开始并执行 DFS 以确定我们是否可以找到目标单词。但我们并没有这样做,为什么呢?
我想了很多,并得出了以下推理,但我不确定 - 我们使用回溯方法是因为同一字母单元不得使用多次。因此,当我们进行回溯时,我们用“*”替换原始字符,然后当我们回来时重新替换它。但这感觉不太对,因为我们本可以使用visited
矩阵代替。