剑指offer-矩阵中的路径

题目描述

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

思路

首先对所整个矩阵遍历,找到第一个字符,然后向上下左右查找下一个字符,由于每个字符都是相同的判断方法(先判断当前字符是否相等,再向四周查找),因此采用递归函数。
由于字符查找过后不能重复进入,所以还要定义一个与字符矩阵大小相同的布尔值矩阵,标记该格子是否进入过,如果进入过该格子的布尔值标记为true;如果不满足的情况下,需要进行回溯,此时,要将该格子的布尔值标记回false。

所用的的回溯就是对使用过的字符进行标记和处理后的去标记

java 实现

public class Solution {
   public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        if (matrix == null || rows <= 0 || cols <= 0 || str == null)
            return false;
        if (str.length == 0)
            return false;
        boolean[] visited = new boolean[matrix.length];
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols; col++) 
                if (findPath(matrix, rows, cols, str, row, col, 0, visited))
                    return true;
        }
        return false;
    }

    boolean findPath(char[] matrix, int rows, int cols, char[] str, int row, int col, int index, boolean[] visited) {
        int countIndex = row * cols + col;//将矩阵形式的计算到下标的具体值
        //格子不符合范围,格子的值不对应str[index]中的值,或者已经访问过 返回false
        if (row < 0 || row >= rows || col < 0 || col >= cols || str[index] != matrix[countIndex] || visited[countIndex])
            return false;
        if (index == str.length - 1)//str所有字符都在格子中找到 返回true
            return true;
        //判断当前格子的值对应str[index]的值,则判断4个相邻格子的值是否为str[index+1]的值
        visited[countIndex] = true;//设置当前位置已经访问过
        if (findPath(matrix, rows, cols, str, row - 1, col, index + 1, visited) ||
                findPath(matrix, rows, cols, str, row, col - 1, index + 1, visited) ||
                findPath(matrix, rows, cols, str, row + 1, col, index + 1, visited) ||
                findPath(matrix, rows, cols, str, row, col + 1, index + 1, visited))
            return true;
        //4个相邻格子的值没有为str[index+1]的值,则str[index]在矩阵中定位不正确,需要回到前一个字符重新定位
        visited[countIndex] = false;//不符合 则退回一步继续判断
        return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值