[LeetCode] 79. Word Search (DFS, backtracking)

topic

Given a two-dimensional grid and a word, to find out whether the word exists in the grid.

Words must, by the letters in adjacent cells constituting alphabetically, where "adjacent" cells that are adjacent horizontally or vertically adjacent cells. Letters within the same cell is not allowed to be reused.

Example:

board =
[
['A','B','C','E'],
['S','F','C','S'],
['A','D','E','E']]

Given word = "ABCCED", returns true.
Given word = "SEE", returns true.
Given word = "ABCB", returns false.

Source: stay button (LeetCode)
link: https://leetcode-cn.com/problems/word-search
copyrighted by deduction from all networks. Commercial reprint please contact the authorized official, non-commercial reprint please indicate the source.

answer

DFS + back

Related

  • The backtracking recursion + understood to prune, and DFS uses recursion backtracking so DFS + feasible approaches are used.
  • About DFS
    • To determine whether to enter in before entering judgment. The logic is clear, and to reduce the access layer.
    • Visited set and then put back in the back into the operation. Avoid writing twice.
    • In fact, these two logic written on the inside and outside can (in addition to the possibility of cross-border into the logic must be written before entering).

Code

class Solution {
    public static boolean exist(char[][] board, String word) {
        if (board == null || board.length == 0) {
            return false;
        }

        boolean[][] visited = new boolean[board.length][board[0].length];// 默认初始化为false,表示未访问过,可走;true表示已访问,不可走。

        for (int i = 0; i < board.length; ++i) {
            for (int j = 0; j < board[0].length; ++j) {
                if (board[i][j] == word.charAt(0)) { // 起始处可不用判断isVaild
                    if (dfs(board, visited, i, j, 0, word)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private static boolean dfs(char[][] board, boolean visited[][], int i, int j, int pos,
            String word) {
        if (pos == word.length() - 1) {
            return true;
        }

        int[] dx = { 0, 0, -1, 1 };
        int[] dy = { -1, 1, 0, 0 };

        visited[i][j] = true;// 进入本点再置本点为已访问,而不是在外面一层处理,避免写两遍。两者效果相同,目的均在于不对其他前缀的路径有影响。
        for (int t = 0; t < 4; ++t) {
            int x = i + dx[t];
            int y = j + dy[t];
            if (isVaild(board, visited, x, y) && board[x][y] == word.charAt(pos + 1)) { //
                if (dfs(board, visited, x, y, pos + 1, word)) {
                    return true;
                }
            }
        }
        visited[i][j] = false;
        return false;
    }

    private static boolean isVaild(char[][] board, boolean[][] visited, int i, int j) {
        return i >= 0 && i < board.length && j >= 0 && j < board[0].length && !visited[i][j];
    }
}

Guess you like

Origin www.cnblogs.com/coding-gaga/p/12072355.html