【算法】单词搜索 (DFS + 回溯)

题目

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

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

示例 1:

img

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true
示例 2:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “SEE”
输出:true
示例 3:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCB”
输出:false

提示:

  • m == board.length
  • n = board[i].length
  • 1 <= m, n <= 6
  • 1 <= word.length <= 15
  • board 和 word 仅由大小写英文字母组成

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/word-search

题解

整体思路

使用DFS(深度优先搜索)和回溯的思想。

外层:遍历

对每个格子都从头开始搜索

for (int i = 0; i < rows; i++) {
    
    
    for (int j = 0; j < cols; j++) {
    
    
        if (dfs(i, j, 0)) {
    
    
            return true;
        }
    }
}

内层:递归

  1. 递归结束条件:匹配到最后一个字母

    • 最后一个字母匹配成功,返回true
    • 最后一个字母匹配失败,返回false
  2. 从(x, y)出发,往四个方向试探,检查坐标是否越界,是否已经访问过

    • 能走,就往下递归

    • 不能走,返回false

marked[x][y] = true;
for (int[] directions: DIRECTIONS) {
    
    
    int newX = x + directions[0];
    int newY = y + directions[1];
    if (inMap(newX, newY) && !marked[newX][newY]) {
    
    
        if (dfs(newX, newY, begin + 1)) {
    
    
            return true;
        }
    }
}
marked[x][y] = false;

实现

class Solution {
    
    
    private static final int[][] DIRECTIONS = new int[][]{
    
    {
    
    1,0},{
    
    0,1},{
    
    -1,0},{
    
    0,-1}};
    private int rows, cols;
    private int len;
    private boolean[][] marked;
    private char[][] board;
    private char[] wordArray;

    public boolean exist(char[][] board, String word) {
    
    
        this.rows = board.length;
        if (rows == 0) return false;
        this.cols = board[0].length;
        if (cols == 0) return false;

        this.marked = new boolean[rows][cols];
        this.board = board;
        this.wordArray = word.toCharArray();
        this.len = word.length();

        for (int i = 0; i < rows; i++) {
    
    
            for (int j = 0; j < cols; j++) {
    
    
                if (dfs(i, j, 0)) {
    
    
                    return true;
                }
            }
        }
        return false;
    }

    private boolean dfs(int x, int y, int begin) {
    
    
        if (board[x][y] != wordArray[begin]) {
    
    
            return false;
        }
        if (begin == len - 1) {
    
    
            return true;
        }

        marked[x][y] = true;
        for (int[] directions: DIRECTIONS) {
    
    
            int newX = x + directions[0];
            int newY = y + directions[1];
            if (inMap(newX, newY) && !marked[newX][newY]) {
    
    
                if (dfs(newX, newY, begin + 1)) {
    
    
                    return true;
                }
            }
        }
        marked[x][y] = false;
        return false;
    }

    private boolean inMap(int x, int y) {
    
    
        return x >= 0 && x < rows && y >= 0 && y < cols;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45177370/article/details/120612810