牛客剑指offer之【JZ12 矩阵中的路径】

哈喽,这次真的是好久不见呀,我回来啦~~接下来的日子我会不断更新牛客上的剑指offer题解,为什么这么做呢?是因为博主刷题总是刷了忘忘了刷,一样的题目换种形式就要做好久,说到底还是对知识点的理解不够透彻,加之算法对一个即将找工作的大学生来说更是重中之重。所以以后我将以写博客的方式来记录我的解题过程,这样既可以做到一个题后总结的作用,又可以起到一个隐形督促作用~~那废话不多说,我们直接开始吧~~

 1.题目

2.示例解读

示例1中给了一个二维数组和一个字符串,要让我们判断,在矩阵中是否存在这样一条路径能与给出的字符串匹配。很显然是存在的,如下图:

但是这条路径是怎样找到的呢?其实很简单,因为路径的起点是可以任意的,所以我们需要遍历这个矩阵中的每一个元素。如果其中以任意一个元素为起点的路径可以与字符串匹配,我们就认为在这个矩阵中是存在这样的一条路径的,反之则不存在。对于路径所到达的最后一个元素,我们需要对它的上下左右每一个方向去依次试探,找到与之匹配的下一个节点,直到匹配完字符串中的所有字符或每一个方向都不能与之匹配位置为止,如下图:

3.解题思路

通过以上分析,我们不难发现这就是一个很典型的回溯问题,就是通过枚举的方式去一个个往下去试探。因为起点可以是矩阵中的任意一个元素,所以我们要对这个二维数组进行遍历。大致如下:

for(int i=0;i<matrix.length;i++){
    for(int j=0;j<matrix[0].length;j++){
        //从matrix[i][j]开始查找
        if(dfs(matrix,i,j,0,word))
            return true;
    }
}       
return false;   

 这里关键就是dfs这个函数的实现,因为每一个点我们在查找的时候可以分上下左右四个方向,其中要排除该路径已经经过的节点,即节点不能被二次匹配。所以我们需要将被匹配到的节点标记一下,以防被再次匹配。大致代码如下:

boolean dfs(char[][] matrix,int x,int y,int n,String word){
        //递归出口
        if(n==word.length())return true;
        if(x<0||y<0||x>=matrix.length||y>=matrix[0].length
        ||matrix[x][y]!=word.charAt(n))return false;

        //代码走到这里说明matrix[x][y]能与之匹配,然后去搜索matrix[x][y]的上下左右节点
        boolean res=false;
        //记录被匹配到的值
        char tmp=matrix[x][y];
        //修改匹配的值,使之永远不会被匹配到(即不存在二次匹配)
        matrix[x][y]='0';

        //上下左右依次搜索
        res=dfs(matrix,x-1,y,n+1,word)||dfs(matrix,x+1,y,n+1,word)||
        dfs(matrix,x,y-1,n+1,word)||dfs(matrix,x,y+1,n+1,word);
        //结束一轮搜索之后回到上一个节点
        matrix[x][y]=tmp;
        return res;
}

4.完整代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    public boolean hasPath (char[][] matrix, String word) {
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<matrix[0].length;j++){
               if(dfs(matrix,i,j,0,word))return true;
            }
        }       
        return false;      
    }
    boolean dfs(char[][] matrix,int x,int y,int n,String word){
        if(n==word.length())return true;
        if(x<0||y<0||x>=matrix.length||y>=matrix[0].length
        ||matrix[x][y]!=word.charAt(n))return false;
        boolean res=false;
        char tmp=matrix[x][y];
        matrix[x][y]='0';
        //上下左右
        res=dfs(matrix,x-1,y,n+1,word)||dfs(matrix,x+1,y,n+1,word)||
        dfs(matrix,x,y-1,n+1,word)||dfs(matrix,x,y+1,n+1,word);
        matrix[x][y]=tmp;
        return res;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆啦A梦的110

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值