79. 单词搜索 - 力扣(LeetCode)

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

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

示例 1:

image

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED"
输出:true

示例 2:

image

输入:board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE"
输出:true

示例 3:

image

输入: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
  • boardword 仅由大小写英文字母组成

**进阶:**你可以使用搜索剪枝的技术来优化解决方案,使其在 board 更大的情况下可以更快解决问题?

通过次数226,583提交次数494,093

一解

使用深度优先遍历,dfs 函数需要判断 x,y 是否越界:0~m,0~n 。利用数组 visited 记录已经遍历过的路径:

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        m, n = len(board), len(board[0])
        self.res = False
        def dfs(x, y, index):
            if 0 <= x < m and 0 <= y < n and (board[x][y] != word[index] or visited[x][y]): 
                return 
            if x >= m or x < 0 or y >= n or y < 0:
                return
            if index == len(word) - 1:
                self.res = True
                return
            visited[x][y] = True
            dfs(x + 1, y, index + 1)
            dfs(x, y + 1, index + 1)
            dfs(x - 1, y, index + 1)
            dfs(x, y - 1, index + 1)
            visited[x][y] = False
        for i in range(m):
            for j in range(n):
                visited = [[False]*n for _ in range(m)]
                dfs(i, j, 0)
                if self.res:
                    return self.res
        return False
  • 时间复杂度 O(mn3^L):除了第一次可以进入 4 个分支以外,其余时间我们最多会进入 3 个分支(因为每个位置只能使用一次,所以走过来的分支没法走回去)。设单词长为 L。
  • 空间复杂度 O(nm)。