矩阵中的路径-剑指Offer-java深度优先

一、题目描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

示例 1:

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"

输出:true

示例 2:

输入:board = [["a","b"],["c","d"]], word = "abcd"

输出:false

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、运行结果

三、解题思路

整体思路:深度优先遍历(递归实现)

遍历输入字符数组中的每个字符,对每个字符都调用一次深度优先遍历(dfs),在dfs中执行如下操作:

递归出口:如果已经找到一条完整的路径(index >=word.length)返回true;如果下标越界或当前字符不匹配,就剪枝,结束当前路径查找,返回false;

如果当前字符匹配,则从四个方向分别进行递归查找,匹配下一个字符;

需要注意的是,不能重复使用数组中的字符,所以在一次递归遍历中,如果当前字符匹配,就将数组该位置的字符置为空格符,然后再向四个方向递归,结束当前递归后,再恢复数组中的该字符。

四、AC代码

class Solution {
    public boolean exist(char[][] board, String word) {
        int row = board.length;
        int col = board[0].length;
        for(int i=0; i<row; i++){
            for(int j=0; j<col; j++){
                boolean flag = dfs(board, word, i, j, 0); //从当前位置开始递归寻找
                if(flag)  //找到了一条完整的路径
                    return true;
            }
        }
        return false;
    }
    // 递归遍历 i, j:数组的行和列索引,index:字符串中字符的索引
    boolean dfs(char[][] board, String word, int i, int j, int index){
        if(index >= word.length())  //已经找到一条完整路径
            return true;
        else if(i<0 || j<0 || i>=board.length || j>=board[0].length || 
            board[i][j] != word.charAt(index))
            return false;
        board[i][j] = ' ';  //防止被重复使用
        // 向四个方向查找匹配下一个字符
        boolean res = dfs(board, word, i+1, j, index+1)||dfs(board, word, i-1, j, index+1) 
                 || dfs(board, word, i, j-1, index+1) || dfs(board, word, i, j+1, index+1);
        board[i][j] = word.charAt(index);  //递归结束,恢复原来的字符
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值