剑指Offer(二)矩阵中的路径

题目:

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

思路:

这道题应当使用的编程思想为回溯法。而实现回溯的方式则为递归。因为不能重复遍历,所以还需要一个可以记录访问状态的布尔数组。所谓回溯法,就是指当遍历时,路径上的某一个值不能符合某一个条件时,则回到上一个节点。

程序代码(含注释)

#include<iostream>
using namespace std;   //这个不用说了吧,C++的头文件标准格式
class Solution {
public:
    bool hasPath(char* matrix, int rows, int cols, char* str)   //这里的matrix即为需要遍历的矩阵,str即为路径字符数组
    {
        if(matrix == NULL || rows < 1 || cols < 1 || str == NULL)
            return false;                                       //边界值判定
        bool *visited=new bool[rows*cols]{0};                   //定义了一个表征是否访问的布尔变量visited,并把初始值设置为false
        //memset(visited,0,rows*cols);
        int index=0;                                            //表征数组下标的变量
        for(int row=0;row<rows;++row)
        {
            for(int col=0;col<cols;++col)
            {
                if(successfindPath(matrix,rows,cols,row,col,index,visited,str))
                    return true;
            }
        }                                                      //遍历矩阵中的每一个点,如果从该点出发可以得到一条str所表示的路径,则返回true,否则,说明该路径不存在
        delete[] visited;                                       //删除visited的内存
        return false;                                           //如果找不到,则返回false
    }
    bool successfindPath(char *matrix,int rows,int cols,int row,int col,int index,bool *visited,char *str)
    {
        if(str[index]=='\0')
            return true;                                        //首先判定字符数组是否已经到头,如果到头,说明遍历结束了。这种表达可以学习一下。
        bool hasPath=false;                                     //表征是否成功遍历的布尔变量
        if(row<=rows && col<=cols && rows>=1 && cols>=1 && matrix!=NULL && str!=NULL && str[index]==matrix[row*cols+col]&& visited[row*cols+col]==false)
        {                                                       //假如该点与数组中的某一个值重合,则首先会把visited标记为1,然后访问它上下左右的四个点。
            visited[row*cols+col]=true;
            ++index;
            hasPath=
              successfindPath(matrix,rows,cols,row+1,col,index,visited,str)
            ||successfindPath(matrix,rows,cols,row,col+1,index,visited,str)
            ||successfindPath(matrix,rows,cols,row-1,col,index,visited,str)
            ||successfindPath(matrix,rows,cols,row,col-1,index,visited,str);
            if(!hasPath)
            {
                --index;
                visited[row*cols+col]=false;
            }
        }
        return hasPath;
    }

};

主程序及测试用例:

int main()
{
    char *matrix=new char[12]{'a','b','c','e','s','f','c','s','a','d','e','e'};
    int rows=3;
    int cols=4;
    char *str=new char[4]{'a','b','c','b'};
    char *str1=new char[5]{'b','c','c','e','d'};
    Solution s;
    bool findResult=s.hasPath(matrix, rows, cols, str);
    if(findResult)
        cout<<1<<endl;
    else
        cout<<0<<endl;
     bool findResult1=s.hasPath(matrix, rows, cols, str1);
    if(findResult1)
        cout<<1<<endl;
    else
        cout<<0<<endl;

}

输入结果:


前者重复遍历了'b'



猜你喜欢

转载自blog.csdn.net/bubbler_726/article/details/80914027