剑指Offer面试题12:矩阵中的路径


判断一个字符矩阵中是否存在着一条包含某个给定字符串的路径。
路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。
说明,从本道题开始使用牛客网的OJ以及参考相关大神的思路。

思路

考点为回溯法
待编辑,完善

解法1

/**
* 面试题12:矩阵中的路径
*
* @author Heroin X
* @date 2019/12/26 16:13
*/
public class PathMatrix {

  public static void main(String[] args) {
      char[] matrix={'a','b','t','g','c','f','c','s','j','d','e','h'};
      int rows=3;int cols=4;
      char[] str={'b','f','c','e'};
//        char[] str={'a','b','f','b'};
      boolean b = hasPath(matrix, rows, cols, str);
      System.out.println(b);
  }


  public static boolean hasPath(char[] matrix, int rows, int cols, char[] str) {

      //还有特殊情况,第一个字符就找不到的时候

      int[] firstPose = getFirstPose(matrix, str,cols);
      int i=firstPose[0];int j=firstPose[1];
      int[][] flag=new int[rows][cols];
      return hasPath(matrix,rows,cols,str,i,j,flag,0);
  }

  private static boolean hasPath(char[] matrix, int rows, int cols, char[] str, int i, int j,int[][] flag,int index) {

      //二维数组转化为一维数组,不懂为什么是这种写法?
      int l=cols*i+j;
//        int l=rows*i+j-1;

      if (i<0 || i>=rows || j<0 || j>=cols || flag[i][j]==1 || matrix[l]!=str[index]){
          return false;
      }

      // 表示全部匹配完成了
      if (index==str.length-1){
          return true;
      }

      // 走完了当前节点,置1
      flag[i][j]=1;

      if (hasPath(matrix,rows,cols,str,i-1,j,flag,index+1)
              || hasPath(matrix,rows,cols,str,i+1,j,flag,index+1)
              || hasPath(matrix,rows,cols,str,i,j-1,flag,index+1)
              || hasPath(matrix,rows,cols,str,i,j+1,flag,index+1)){

          return true;
      }

      // 表示失败了
      flag[i][j]=0;
      return false;
  }

  /**
   * 找到字符串首字符的位置
   * @param matrix
   * @param str
   * @param cols
   * @return
   */
  static int[] getFirstPose(char[] matrix, char[] str,int cols){
      for (int i=0;i<matrix.length;i++){
          if (matrix[i]==str[0]){
              int y = i % cols;
              int x = i/cols;
              return new int[]{x,y};
          }
      }
      return new int[]{-1,-1};
  }
}

解法2

nowcoder的AC
提交时间:2019-12-30 ,语言:Java ,运行时间: 29 ms ,占用内存:9632K ,状态:答案正确
(1)起始点的问题。解法1中的那种先找到起始点的方式在起始点有多个的情况下且第一个起始点不通时无法Accept,需要改进为解法2这种,从(0,0)坐标开始遍历。
(2)关于二维数组坐标与一维数组坐标位置转化的问题。int l=cols*i+j;是OK的,而int l=rows*i+j-1;实际是错我的,在于横纵坐标点位均是从0开始的。同时int x = i/cols; int y = i % cols;是同样的道理。

public class Solution {
 public  boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
       
     int[][] flag=new int[rows][cols];
     //从左上角(0,0)开始遍历
      for(int i=0;i<rows;i++){
          for(int j=0;j<cols;j++){
              if(hasPath(matrix,rows,cols,str,i,j,flag,0)){
                  return true;
              }
          }
      }
      return false;
  }

  private  boolean hasPath(char[] matrix, int rows, int cols, char[] str, int i, int j,int[][] flag,int index) {
       
      //二维数组转化为一维数组,小心
      int l=cols*i+j;
//        int l=rows*i+j-1;

      if (i<0 || i>=rows || j<0 || j>=cols || flag[i][j]==1 || matrix[l]!=str[index]){
          return false;
      }

      // 表示全部匹配完成了
      if (index==str.length-1){
          return true;
      }

      // 走完了当前节点,置1
      flag[i][j]=1;

      if (hasPath(matrix,rows,cols,str,i-1,j,flag,index+1)
              || hasPath(matrix,rows,cols,str,i+1,j,flag,index+1)
              || hasPath(matrix,rows,cols,str,i,j-1,flag,index+1)
              || hasPath(matrix,rows,cols,str,i,j+1,flag,index+1)){

          return true;
      }

      // 表示失败了
      flag[i][j]=0;
      return false;
  }
  
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值