1 题目
https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/
2 题意
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。
[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]
但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。
示例 1:
输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true
示例 2:
输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false
提示:
1 <= board.length <= 200
1 <= board[i].length <= 200
3 思路
author's blog == http://www.cnblogs.com/toulanboy/
本题要求判断图中是否存在一条指定的路径。求起点到终点的问题,我们可以借助深度优先搜索解决。
具体方案为:
先找出第0个字符在矩阵中出现的位置,然后基于这个位置判断四周是否存在第1个字符。然后再基于第1个字符判断四周是否存在第2个字符,以此类推,直到找到第n个字符。
可以发现上述过程实际上都是由相同的子过程组成,只是这些子过程的参数不一样。所以,我们只需写一个函数,负责判断第i个位置附近是否有第i+1字符,然后递归调用即可。
4 代码
//author's blog == http://www.cnblogs.com/toulanboy/
class Solution {
public:
int direction[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};//方向偏移量
bool visit[201][201];//访问标志,避免重复使用同一位置的字符
//dfs(): 判断(x, y)周围是否有word[pos]。
bool dfs(int x, int y, int pos, vector<vector<char>>& board, string& word){
if(pos >= word.size()){
return true;
}
int n = board.size();
int m = board[0].size();
for(int i=0; i<4; ++i){//4个方向
int new_x = x + direction[i][0];
int new_y = y + direction[i][1];
//合法性判断
if(new_x >= 0 && new_x < n && new_y >=0 && new_y < m && visit[new_x][new_y]==false){
if(board[new_x][new_y] == word[pos]){//如果(x, y)周围是否有word[pos],
visit[new_x][new_y] = true;
if(dfs(new_x, new_y, pos+1, board, word)){//那么判断(new_x, new_y)周围是否有word[pos+1]
return true;
}
visit[new_x][new_y] = false;
}
}
}
return false;
}
bool exist(vector<vector<char>>& board, string word) {
memset(visit, 0, sizeof(visit));
//先找到第0个字符在矩阵中出现位置,然后基于这个位置找下一位数字
for(int i=0; i<board.size(); ++i){
for(int j=0; j<board[i].size(); ++j){
if(board[i][j] == word[0]){//如果(i, j)出现了word[0]
visit[i][j] = true;
if(dfs(i, j, 1, board, word)){//判断(i, j)周围是否有word[1]
return true;
}
visit[i][j] = false;
}
}
}
return false;
}
};