【剑指Offer】面试题66:矩阵中的路径

来源:互联网 发布:淘宝衣服好评语大全 编辑:程序博客网 时间:2024/06/01 09:10

一:题目描述

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

举例分析
例如在下面的 3*4 的矩阵中包含一条字符串“bcced”的路径。但矩阵中不包含字符串“abcb”的路径,因为字符串的第一个字符 b 占据了矩阵中的第一行第二格子之后,路径不能再次进入这个格子。

a b c e s f c s a d e e

二:解题思路

参看剑指Offer

这是可以用回溯法解决的典型题

由于回溯法的递归特性,路径可以看成是一个栈,当在矩阵中定位了路径的前n个字符的位置之后,在与第n个字符对应的格子周围没有找到第n+1个字符,这个时候只好在路径上回到第n-1个字符,重新定义第n个字符

由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入过每一个格子

三:代码实现

class Solution {public:    bool hasPath(char* matrix, int rows, int cols, char* str)    {        if(matrix==NULL || rows<1  || cols<1 || str==NULL)            return false;        //定义布尔值矩阵,用来识别路径是否已经进入过每一个格子        bool* visited=new bool[rows*cols];        memset(visited,0,rows*cols);                int pathLength=0;        //以矩阵的每一个格子,作为起始,只要有一条路径满足要求,就返回true        for(int row=0;row<rows;row++)            for(int col=0;col<cols;col++)                if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited))                    return true;        delete[] visited;        return false;        }        bool hasPathCore(char* matrix,int rows,int cols,int row,int col ,char* str,int &pathLength,bool* visited){        //字符串全部遍历完,返回true        if(str[pathLength]=='\0')            return true;        bool hasPath=false;        //当前格子与字符串的当前字符相等,且格子没有被遍历过,则寻找当前字符成功        if(row>=0 && row<rows && col>=0 && col<cols            && matrix[row*cols+col]==str[pathLength] && !visited[row*cols+col]){            pathLength++;//寻找下一个字符            visited[row*cols+col]=true;            //从上下左右四个方向搜索是否能够匹配字符            hasPath=hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited) ||                hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited) ||                hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited) ||                hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited);        //如果当前格子上下左右四个方向都不能匹配,说明当前格子虽然匹配成功当前字符,        //但是不能成功匹配下一个字符,则当前格子不是可行解中的格子,所以解除对当前格子的占用        if(!hasPath){            pathLength--;            visited[row*cols+col]=false;        }        }//if        return hasPath;    }};

原创粉丝点击