剑指offer NO12 矩阵中的路径 详解

public class Solution
{
    //定义的是每次行走的方向。
    private final static int[][] next = {
            {0,-1},{0,1},{1,0},{-1,0}
    };

    //用来记录二位数组的行与列
    private int rows;
    private int cols;

    public boolean hasPath(char[] arr, int rows,int cols,char[] str)
    {
        if (rows == 0 || cols == 0)
            return false;
        
        this.rows = rows;
        this.cols = cols;

        //定义一个数组来记录当前遍历的这个字符是否符合条件。
        boolean[][] marked = new boolean[rows][cols];

        //要把传入的字符数组转变为二维数组,这样才好进行操作
        char[][] matrix = bulidMatrix(arr);
        //把每一个矩阵元素作为起点传入回溯方法中,来判断是否有符合条件的。
        for (int i = 0; i < rows; i ++)
            for (int j = 0; j < cols; j++)
                if (backtracking(matrix,str,marked,0,i,j))
                    return true;

        return false;
    }

    private boolean backtracking(char[][] matrix, char[] str, boolean[][] marked, int pathLen, int r, int c)
    {
        //递归出口
        //1.正确的出口。在矩阵中找到的字符个数等于目标的。即找到了目标字符数组。
        if (pathLen == str.length)
            return true;

        //2.错误的出口。 行 列 越界,或者此次递归矩阵的元素 与 目标 字符 不相等
        //或者 这个元素已经走过并且已经判定为不合适。
        if (r < 0 || r > rows || c < 0 || c > cols || matrix[r][c] != str[pathLen] || marked[r][c])
            return false;


        //只有符合条件的元素才能进入
        //进入的都是符合条件的元素,把标记数组设为true
        marked[r][c] = true;

        //以此元素为原点, 开始往各个方向走; panlen + 1;
        for (int[] n : next)
        {
            if (backtracking(matrix,str,marked,pathLen + 1,r + n[0],c + n[0]))
                return true;
        }
        //没有正确的值得话,证明这个矩阵元素不行,标记数组设为false
        //并返回false 回溯到上一级再进行判断
        marked[r][c] = false;
        return false;
    }
    //转换为矩阵
    private char[][] bulidMatrix(char[] arr)
    {
        char[][] matrix = new char[rows][cols];
        for (int r = 0, index = 0; r < rows; r ++)
        {
            for (int c = 0; c < cols; c ++)
                matrix[r][c] = arr[index++];
        }
        return matrix;
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值