矩阵中的路径

矩阵中的路径

1、参考资料

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

2、题目要求

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

[“a”,“b”,“c”,“e”],
[“s”,“f”,“c”,“s”],
[“a”,“d”,“e”,“e”]]

但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入这个格子。

示例 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

3、代码思路

假设二维字符数组为:

char[][] board = {
    {'a', 'b', 'c', 'e'},
    {'s', 'f', 'c', 's'},
    {'a', 'd', 'e', 'e'},
};

待寻找的路径为 "bfce"


  1. 一看到这种寻找路径的题目,想都不用想,肯定是用深度优先搜索
  2. 首先给定一个起点,比如说 row = 0; col = 1,则起点 board[row][col] = 'b',首先,我们从起点向上、向下、向左、向右搜索,如果搜索不到目标字符则返回 false,表示此路不通,如果能够搜索到目标字符,则在目标字符的基础上,继续向上、向下、向左、向右搜索
  3. 如果搜索到最后一个字符 e 都能匹配上,则说明此路畅通,返回 true,表示找到目标路径
  4. 从上面的过程来看,这明显就是一个递归搜索的过程,"bfce" 这条路径到底能不能走通,则需要走到字符 e(递归至最深层),才能知道此路径能走通;如果当前位置向上、向下、向左、向右都不能走通,则此路不通,需要回溯至上一层

4、代码实现

代码

/**
 * @ClassName RectanglePathDemo
 * @Description TODO
 * @Author Heygo
 * @Date 2020/8/29 10:21
 * @Version 1.0
 */
public class RectanglePathDemo {

    public static void main(String[] args) {
        char[][] board = {
                {'a', 'b', 'c', 'e'},
                {'s', 'f', 'c', 's'},
                {'a', 'd', 'e', 'e'},
        };
        String word = "bcce";
        boolean exist = exist(board, word);
        System.out.println(exist);
    }

    /**
     * 判断 board 数组中是否存在目标路径 word
     * @param board 字符数组
     * @param word  待匹配的字符串
     * @return      是否找到目标路径
     */
    public static boolean exist(char[][] board, String word) {
        // Guard Safe
        if (word == "" || word == null) {
            return false;
        }
        // 遍历二维数组,以每个字符为起点,尝试深度遍历,找到目标路径
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                // 如果找到则返回 true
                if (dfs(board, word, i, j) == true) {
                    return true;
                }
            }
        }
        // 走到这里,说明没有找到目标路径,返回 false
        return false;
    }

    /**
     * 深度遍历,在 board 数组中寻找目标 word 路径
     * @param board 字符数组
     * @param word  待匹配的字符串
     * @param row   当前行索引
     * @param col   当前列索引
     * @return      深度遍历的结果,即是否成功找目标字符串的路径
     */
    public static boolean dfs(char[][] board, String word, int row, int col) {
        // 如果 word == "",表示匹配到全部字符,找到路径,返回 true
        if ("".equals(word)) {
            return true;
        }

        // 否则,取出字符串中第一个字符
        Character destChar = word.charAt(0);

        // 1.如果行指针和列指针超出数组界限,或者
        // 2.如果 board[row][col] 元素不是目标字符
        // 则返回 false,表示没找到
        if (row < 0 || row >= board.length || col < 0 || col >= board[0].length || board[row][col] != destChar) {
            return false;
        }

        // 保存当前位置的字符
        char tepChar = board[row][col];
        // 将当前元素的字符修改为 '$'(不是字母即可)
        board[row][col] = '$';

        // 走到这里,就说明当前字符符合要求,则继续向上、向下、向左、向右进行深度遍历
        boolean result =
                dfs(board, word.substring(1), row - 1, col) ||
                dfs(board, word.substring(1), row + 1, col) ||
                dfs(board, word.substring(1), row, col - 1) ||
                dfs(board, word.substring(1), row, col + 1);


        // 回溯后恢复原位置的字符
        board[row][col] = tepChar;

        // 返回深度遍历的结果
        return result;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值