leetcode
leetcode 2551 ~ 2600
字母迷宫

字母迷宫

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 208 ms, 内存: 18.4 MB


/*
 * 思路:
 * 1. 使用Stream API来简化遍历操作。
 * 2. 由于Stream API不适合处理复杂的递归操作,因此这里只能在基础遍历中使用。
 * 3. 核心逻辑仍然使用DFS进行深度优先搜索。
 */

import java.util.stream.IntStream;

public class Solution {
    public boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;
        boolean[][] visited = new boolean[m][n];
        return IntStream.range(0, m)
                .boxed()
                .flatMap(i -> IntStream.range(0, n)
                        .mapToObj(j -> new int[]{i, j}))
                .anyMatch(pos -> dfs(board, word, 0, pos[0], pos[1], visited));
    }

    private boolean dfs(char[][] board, String word, int index, int x, int y, boolean[][] visited) {
        if (index == word.length()) {
            return true;
        }
        if (x < 0 || y < 0 || x >= board.length || y >= board[0].length || visited[x][y] || board[x][y] != word.charAt(index)) {
            return false;
        }
        visited[x][y] = true;
        boolean found = dfs(board, word, index + 1, x + 1, y, visited) ||
                        dfs(board, word, index + 1, x - 1, y, visited) ||
                        dfs(board, word, index + 1, x, y + 1, visited) ||
                        dfs(board, word, index + 1, x, y - 1, visited);
        visited[x][y] = false;
        return found;
    }
}

解释

方法:

此题解采用深度优先搜索(DFS)策略来遍历字母迷宫,并试图在其中寻找目标单词。从迷宫的每一个格子开始,尝试向四个方向(上、下、左、右)扩展搜索,以匹配目标单词的每个字符。搜索过程中使用递归函数dfs(i, j, k)来实现,其中i和j表示当前的行和列位置,k表示目标单词中当前正在匹配的字符索引。如果当前位置越界或字符不匹配,则返回False。如果所有字符都成功匹配(即k等于单词长度减一),则返回True。为了防止在DFS过程中重复使用同一单元格,将当前单元格的值暂时设置为空字符串,并在搜索返回后恢复原值。只要从任意起点开始的DFS返回True,就表示可以在迷宫中找到目标单词。

时间复杂度:

O(m*n*4^L)

空间复杂度:

O(L)

代码细节讲解

🦆
在DFS中,如何有效地处理格子的临时标记和恢复过程,以确保不影响其他搜索路径?
在DFS搜索过程中,为了避免重复访问同一个格子,需要暂时将当前格子标记为已访问。这通常通过修改格子的内容来实现,例如将当前格子的字符暂时设置为空字符串或其他特殊标记。在DFS的每一层递归调用之后,重要的是要将格子恢复到原始状态,以使这个格子可以在其他搜索路径中被重新使用。这种方法确保了每次搜索路径都是独立的,并且棋盘的状态在每次搜索后都会被正确地恢复。
🦆
DFS递归调用栈在最坏情况下的深度是如何计算的,考虑到单词长度和棋盘的大小?
DFS递归调用栈的最大深度主要取决于目标单词的长度。在最坏情况下,如果整个棋盘几乎或完全匹配整个单词,那么递归的深度可能会达到单词的长度。这是因为每递归一次,都会向前匹配单词的下一个字符。棋盘的大小影响的是递归的广度,即从每个格子开始的可能的搜索路径数量,但最大深度仍然由单词长度决定。
🦆
为什么选择深度优先搜索而不是广度优先搜索来解决这个问题?广度优先搜索在这个场景中的表现如何?
深度优先搜索(DFS)在这种类型的问题中被选择,主要是因为它能够快速深入探索可能的单词匹配路径,一旦找到匹配就可以立即返回成功,不需要完全遍历所有路径。相比之下,广度优先搜索(BFS)则会层层扩展,需要更多的内存来存储在每一层搜索中的所有可能状态,而且在找到完整匹配前不会停止。在寻找单一解的问题中,DFS往往更有效率。不过,BFS在找到最短路径问题中更有优势。
🦆
在代码实现中,如果单词的第一个字符在棋盘中出现多次,算法是否会尝试所有可能的起始位置?
是的,在给定的代码实现中,算法会遍历棋盘中的每一个格子作为起始点,并尝试从每个包含单词第一个字符的格子开始执行DFS。这意味着如果单词的第一个字符在棋盘上出现多次,算法会从这些格子中的每一个开始搜索,以尝试找到完整的单词。这样做确保了不会错过任何可能的匹配路径。

相关问题