剑指Offer 面试题12. 矩阵中的路径
解题思路:
利用DFS加回溯的思路,寻找所有可能的路径。分别向上、左、下、右四个方向寻找,如果有一个方向走得通,则返回true,如果都走不通,说明当前元素无法形成路径,要进行回溯。
源代码:
class Solution {
private:
int len;
bool vis[1000][1000] = {false};
public:
bool helper(vector<vector<char>>& board, string word, int c_x, int c_y){
/*这里注意一下,这两个if语句的顺序不能写反,因为
如果当前len == word.length(),但是两个字符却不匹配
则返回的是true而不是正确的结果。
*/
if(c_x < 0 || c_x >= board.size() || c_y < 0 || c_y >= board[0].size() || board[c_x][c_y] != word[len - 1] || vis[c_x][c_y]) return false;
if(len == word.length()) return true;
// 记录当前走过的元素,防止重复
vis[c_x][c_y] = true;
len ++;
// 向四个方向进行dfs搜索
bool left = helper(board, word, c_x, c_y -1);
bool right = helper(board, word, c_x, c_y +1);
bool up = helper(board, word, c_x -1, c_y);
bool down = helper(board, word, c_x +1, c_y );
// 如果有一个方向能走通,则整个路径就是可行的
if(left || right || up || down) return true;
// 四个方向都走不通,就进行回溯,搜索长度减1,
// 当前元素的visited数组对应的bool值改为false
len --;
vis[c_x][c_y] = false;
return false;
}
bool exist(vector<vector<char>>& board, string word) {
int i,j;
len = 0;
bool res = false;
// 将特殊情况的矩阵排除,
// 像矩阵元素的个数比word长度都小这种
if(board.size() <= 0 || board[0].size() <= 0 || (board.size() * board[0].size()) < word.length()) return res;
for(i=0;i<board.size();i++){
for(j=0;j<board[0].size();j++){
if(board[i][j] == word[0]){
/* 这里要注意一下,找到第一个匹配的元素之后
不要直接就退出循环,因为这个字母很可能走不通
但是下面有其他一样的字符可以走通,要挨个判断
找出能走通的那个起点
*/
len = 1;
res = helper(board, word, i, j);
if(res) return true;
}
}
}
return false;
}
};