矩阵中的路径

题目描述
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路:这是一道剑指offer上的题目,这是一道经典的回溯算法的题,然而我做的时候并没有想到回溯法,只是受到之前做的有关正则表达式匹配的算法的启发(我之前的博客有),大概的思路就是当前值的正确性与下一个值有关系,所以不仅要验证当前值是否正确,还要看下一个值是否也正确,所以就会产生类似如下的代码:
ans=curAns&&nextAns
这样的话很容易就想到了递归,想到了递归之后再在算法里面匹配各种情况,分析各个条件的正确性,也就能得出答案了。还有一点比较受启发的是善用与或逻辑表达式,能减少很多if else表达式。
下面是我的实现代码:

public class Solution {
    char[][]m;
    int rows,cols;
    boolean[][] steps;//用来存放已走过的步
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
    {
        this.rows=rows;
        this.cols=cols;
       
        m=new char[rows+1][cols+1];
        int index=0;
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
                m[i][j]=matrix[index++];
            }
        }
        boolean ans=false;
        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
               if(m[i][j]==str[0]){
            	 steps=new boolean[rows][cols];
                  ans=searchM(0,str,i,j);
                  if(ans==true)
                	  return ans;
               }
            }
        }
        return ans;
        //从矩阵里把头找出来,逐个头匹配
    }
    boolean searchM(int index,char[] str,int row,int col){
        //向上,向左,向右,向下探测,某一方向探测失败则往另一个方向探测,四个方向都探测失败,则失败
        //探测过程注意矩阵不要越界
    	if(steps[row][col])//已经走过了
        	return false;
//        if(index==str.length)//前面的都匹配成功了
//            return true;//看是否匹配到了最后一个
        
        steps[row][col]=true;//走过
        boolean ans,curMatch=false;
        if(m[row][col]==str[index])
            curMatch=true;
        //当前匹配或者四个方向下一个字符匹配
        boolean up,down,left,right;

        //当前匹配才继续判断下一个是否合适
        //里面是判断能否往下一步走的条件,当到最后一个不能再往下一步走了,就看他是否是最后一个
        up=curMatch&&((index+1<str.length&&row-1>=0&&!steps[row-1][col]&&searchM(index+1,str,row-1,col))||index==str.length-1);//从哪个方向来,所以应该相反,从上面来,就是不用再往上走了
        down=curMatch&&((index+1<str.length&&row+1<rows&&!steps[row+1][col]&&searchM(index+1,str,row+1,col))||index==str.length-1);
        left=curMatch&&((index+1<str.length&&col-1>=0&&!steps[row][col-1]&&searchM(index+1,str,row,col-1))||index==str.length-1);
        right=curMatch&&((index+1<str.length&&col+1<cols&&!steps[row][col+1]&&searchM(index+1,str,row,col+1))||index==str.length-1);
             
        ans=(up||down||left||right);//有一个方向正确即可
        if(ans==false)//该点不正确,当没走过
        	steps[row][col]=false;
        return  ans;
    }
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值