Loading

Medium | LeetCode 79 | 剑指 Offer 12. 矩阵中的路径 | 回溯(矩阵 + DFS)

剑指 Offer 12. 矩阵中的路径

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的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

提示:

  • 1 <= board.length <= 200

  • 1 <= board[i].length <= 200

解题思路

以目标字符串的首个字符为起点, 对矩阵进行深度优先遍历即可, 并且在遍历过程中, 将深度优先遍历的深度作为参数传给下一个递归方法, 也就是此遍历深度的字符 与目标字符串的下标的字符 应当相等, 如果不相等, 应当进行剪枝, 搜索下一个位置。

private boolean[][] visit;
private int row;
private int colume;
private int[][] delta;

public boolean exist(char[][] board, String word) {
    // 定义矩阵DFS遍历的四个方向
    delta = new int[][]{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
    row = board.length;
    colume = board[0].length;
    // DFS遍历需要的访问数组
    visit = new boolean[row][colume];
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < colume; j++) {
            if (word.charAt(0) == board[i][j]) {
                // 根据字符串首字幕找到起点
                if (dfs(board, word, 0, i, j)) {
                    return true;
                }
            }
        }
    }
    return false;
}

public boolean dfs(char[][] board, String word, int index, int x, int y) {
    // 只有相同的字符才会进入到搜索过程
    if (word.charAt(index) == board[x][y]) {
        if (index == word.length() - 1) {
            return true;
        }
        visit[x][y] = true;
        for (int i = 0; i < 4; i++) {
            int newx = x + delta[i][0];
            int newy = y + delta[i][1];
            if ((newx >= 0 && newx < row && newy >= 0 && newy < colume) &&
                        !visit[newx][newy] &&
                        dfs(board, word, index + 1, newx, newy)) {
                return true;
            }
        }
    }
    // 否则, 直接返回false进行剪枝
    visit[x][y] = false;
    return false;
}
posted @ 2021-01-17 10:40  反身而诚、  阅读(42)  评论(0编辑  收藏  举报