矩阵中的路径(剑指offer)

题目来自牛客网剑指offer专题:链接

题目描述

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

解题思路

因为要找出一条路径,使得路径按顺序经过的字符刚好可以组成给出的字符串,因此很容易想到使用回溯法,暴力dfs出满足条件的路径。

具体思路是用一个全初始化为0的二维矩阵arr记录每个位置是否经过,然后从矩阵matrix的每一个位置出发做dfs,每次dfs都要考虑上下左右四个方向,不越界才进行递归搜索,走了一个新的格子之后要将arr中该格子所处位置的值置为1,递归结束的条件为找到包含该字符串的完整路径或当前所处格子的字符与字符串对应位置的字符不同。

最后回到上一层递归中接收答案,如果有解就返回true,无解返回false。

AC代码

运行时间:5ms

占用内存:504k

class Solution {
public:
    char *m;
    char *s;
    int row;
    int col;
    bool hasPath(char* matrix, int rows, int cols, char* str)
    {
        m=matrix;
        s=str;
        row=rows;
        col=cols;
        vector<vector<int> > arr(rows);		//记录是否经过该位置
        for(auto &i:arr)
            i.resize(cols,0);
        for(int i=0;i<arr.size();i++)
            for(int j=0;j<arr[0].size();j++){
                if(getans(arr,0,i,j))
                    return true;
            }
        return false;
    }
    bool getans(vector<vector<int> > arr,int nowpos,int x,int y){
        bool ans1,ans2,ans3,ans4;
        ans1=ans2=ans3=ans4=false;
        arr[x][y]=1;
        if(m[x*col+y]==s[nowpos]&&nowpos==strlen(s)-1)	//找到字符串对应的路径
            return true;
        if(m[x*col+y]!=s[nowpos])	//当前格子的字符和字符串中对应位置的字符不同
            return false;
        if(y>=1&&!arr[x][y-1])	//左
            ans1=getans(arr,nowpos+1,x,y-1);
        if(y<col-1&&!arr[x][y+1])	//右
            ans2=getans(arr,nowpos+1,x,y+1);
        if(x>=1&&!arr[x-1][y])	//上
            ans3=getans(arr,nowpos+1,x-1,y);
        if(x<row-1&&!arr[x+1][y])	//下
            ans4=getans(arr,nowpos+1,x+1,y);
        if(ans1||ans2||ans3||ans4)
            return true;
        return false;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值