算法刷题系列——DFS:矩阵中的路径

问题描述

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

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

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

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
在这里插入图片描述

思路

首先整体思路是DFS这肯定是没错的,所以基本上也是就在DFS的模板上修改。
但是如果只是单纯的使用模板的话会导致有些情况搜索不到,因为我们修改的visited数组会导致下一个起始位置开始的遍历无法遍历所有可能。
visited数组的作用

  1. 在DFS搜素的整体可能性上来说,避免重复搜索导致效率降低(剪枝——效率问题);
  2. 在单次DFS搜索中,避免两次递归重复调用(形成递归环),导致Stack Overflow(正确性问题).

而在这道题中,我们不能让作用1生效,避免一个起点的遍历情况影响另一个起点的遍历情况。
但是如果没有作用2,那么DFS无法执行,所以这道题要用回溯的思想,在递归结束后(回溯的过程),把visited数组修改回去,这样作用1就不会生效。由于已经在回溯了,此时visited数组的状态变化不会执行的过程产生影响。

Code

class Solution {
    
    
    public boolean exist(char[][] board, String word) {
    
    
        if (word.length() == 0) {
    
    
            return false;
        }
        boolean[][] visited = new boolean[board.length][board[0].length];
        char[] chs = word.toCharArray();
        for (int i = 0; i < board.length; i++) {
    
    
            for (int j = 0; j < board[0].length; j++) {
    
    
                if (board[i][j] == chs[0]) {
    
    
                    if (DFS(board, chs, 0, i, j, visited)) {
    
    
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public boolean DFS(char[][] board, char[] chs, int idx, int x, int y, boolean[][] visited) {
    
    
        if (idx == chs.length) {
    
    
            return true;
        }
        if (x < 0 || y < 0 || x >= board.length || y >= board[0].length) return false;
        // 保证作用1生效
        if (visited[x][y]) {
    
    
            return false;
        }
        if (board[x][y] != chs[idx]) {
    
    
            return false;
        }
        visited[x][y] = true;
        boolean res = 
        DFS(board, chs, idx+1, x-1, y, visited) || 
        DFS(board, chs, idx+1, x+1, y, visited) ||
        DFS(board, chs, idx+1, x, y-1, visited) ||
        DFS(board, chs, idx+1, x, y+1, visited);     
        // 回溯  
        visited[x][y] = false;
        return res;
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_38684427/article/details/119392134