LeetCode 79. 单词搜索 | Python

79. 单词搜索


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

题目


给定一个二维网格和一个单词,找出该单词是否存在于网格中。

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

示例:

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

给定 word = "ABCCED", 返回 true
给定 word = "SEE", 返回 true
给定 word = "ABCB", 返回 false

提示:

  • board 和 word 中只包含大写和小写英文字母。
  • 1 <= board.length <= 200
  • 1 <= board[i].length <= 200
  • 1 <= word.length <= 10^3

解题思路


思路:DFS、回溯

先审题,题目给定一个二维数组和一个单词,需要求出单词是否存在于网格中。

其中判断单词是否存在于二维数组中的依据是:

  • 单词存在于二维数组必须是按照字母顺序,且构建单词字母必须是相邻单元格(相邻单元格表示当前单元格四个方位相邻的其他单元格)
  • 同个单元格的字母不能重复使用。

那么,我们可以发现要去判断单词是否存在于二维数组中,首先我们需要先找到单词的起始字母,然后再向四周扩散搜索。具体的思路如下:

  • 默认从坐标 (0, 0) 开始搜索,先找到单词首字母,然后对其先进行标记(防止同个单元格被重复使用);
  • 然后向四个方位进行扩散搜索(注意限定边界,以及注意是否已被标记),对单元格的字母与单词中的字母继续比对:
    • 若匹配,则进行标记,继续扩散搜索;
    • 若不匹配,则尝试其他方位;
    • 若完全不匹配(四个方位都不匹配),则进行回退,同时释放当前单元格的标记。
  • 重复上面的步骤:
    • 当单词完全匹配,可直接返回 True;
    • 若所有单元格均搜索无果,则返回 False。

这里放个图示,若单纯看文字难以理解,可结合图示进行理解(这里二维数组用网格表示):

LeetCode 79. 单词搜索 | Python_第1张图片

具体代码实现如下。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m = len(board)
        n = len(board[0])

        visited = [[False] * n for _ in range(m)]

        rows = [-1, 0, 1, 0]
        cols = [0, 1, 0, -1]

        def dfs(x, y, idx):
            """搜索单词
            Args:
                x: 行索引
                y: 列索引
                idx: 单词对应的字母索引
            """
            if board[x][y] != word[idx]:
                return False
            
            if idx == len(word) - 1:
                return True
            
            # 先标记
            visited[x][y] = True

            # 找到符合的字母时开始向四个方向扩散搜索
            for i in range(4):
                nx = x + rows[i]
                ny = y + cols[i]
                if 0 <= nx < m and 0 <= ny < n and not visited[nx][ny] and dfs(nx, ny, idx+1):
                        return True
            # 扩散未搜索对应的字母,释放标记
            # 继续往其他方位搜索
            visited[x][y] = False
            return False

        for x in range(m):
            for y in range(n):
                if dfs(x, y, 0):
                    return True
        
        return False

欢迎关注


公众号 【书所集录】

你可能感兴趣的:(LeetCode,dfs,leetcode,算法,python,回溯)