65、矩阵中的路径 超级经典的题目

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。

示例1

输入

"ABCESFCSADEE",3,4,"ABCCED"

返回值

true

示例2

输入

"ABCESFCSADEE",3,4,"ABCB"

返回值

false
1、DFS
//这道题是典型的深度优先遍历DFS的应用,原二维数组就像是一个迷宫,可以  //上下左右四个方向行走
//我们的二维数组board中每个数都作为起点和给定的字符串做匹配,我们需要
//一个和原二维数组board等大小的visited数组,是bool型的,用来记录当前位置
//是否被访问过。因为题目要求一个cell只能被访问一次。
//如果二维数组的当前字符和目标字符串str对应的字符相等,则对其上下左右四个邻字
//符串分别调用dfs的递归函数,只要有一个返回true,那么就表示找到对应的字符串 

bool dfs(vector<vector<char>> &board, char* str, int index, int x, int y,
    vector<vector<bool>>& visited) 

{
    if (index == strlen(str)) return true;//搜寻超过路径长度,符合条件,返回true,//此时已经超过最大程度了 strlen返回不带 ‘\0’的长度,此时str[k]已经越界了,所以这个判断一定要放在函数开头,如果放在if之后,str[k]会越界
    if ((x < 0) || (y < 0) || (x >= board.size()) || (y >= board[0].size()))
        return false;//访问越界,终止,返回false
    if (visited[x][y]) return false;//之前访问过,剪枝
    if (board[x][y] != str[index]) return false;//不相等,剪枝
    visited[x][y] = true;
    if (dfs(board, str, index + 1, x, y - 1, visited) || //上
        dfs(board, str, index + 1, x, y + 1, visited) ||     //下
        dfs(board, str, index + 1, x - 1, y, visited) ||     //左
        dfs(board, str, index + 1, x + 1, y, visited))      //右
        return true; //有符合要求的

    visited[x][y] = false;//记得此处改回false,以方便下一次遍历搜索。
    return false;
}

bool hasPath(char* matrix, int rows, int cols, char* str)
{
    if (str == NULL || rows <= 0 || cols <= 0)
        return false;
    vector<vector<char>> board(rows, vector<char>(cols));
    for (int i = 0; i < rows; ++i) {//将matrix装入二维数组board中
        for (int j = 0; j < cols; ++j) {
            board[i][j] = matrix[i * cols + j];
        }
    }
    vector<vector<bool>> visited(rows, vector<bool>(cols, false));
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            if (dfs(board, str, 0, i, j, visited) == true)
                return true;//以矩阵board中的每个字符为起点进行广度优先搜索
            //找到一个符合条件的即返回true.
        }
    }
    return false;//遍历完都没