python-leetcode 59.单词搜索

发布于:2025-04-01 ⋅ 阅读:(15) ⋅ 点赞:(0)

题目:

给定一个m*n的二维字符网格board和一个字符串单词word,如果word存在于网格中,返回True,否则返回False

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


方法一:回溯

 设函数 check(i,j,k) 表示判断以网格的 (i,j) 位置出发,能否搜索到单词 word[k..],其中 word[k..] 表示字符串 word 从第 k 个字符开始的后缀子串。如果能搜索到,则返回 true,反之返回 false。函数 check(i,j,k) 的执行步骤如下:

 如果 board[i][j]=word[k],当前字符不匹配,直接返回 false

如果当前已经访问到字符串的末尾,且对应字符依然匹配,此时直接返回 true

否则,遍历当前位置的所有相邻位置。如果从某个相邻位置出发,能够搜索到子串 word[k+1..],则返回 true,否则返回 false。

对每一个位置 (i,j) 都调用函数 check(i,j,0) 进行检查:只要有一处返回 true,就说明网格中能够找到相应的单词,否则说明不能找到。

为了防止重复遍历相同的位置,需要额外维护一个与 board 等大的 visited 数组,用于标识每个位置是否被访问过。每次遍历相邻位置时,需要跳过已经被访问的位置。

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        directions=[(0,1),(0,-1),(1,0),(-1,0)] #定义四个方向(右,左,下,上)的移动方式
        def check(i,j,k): #函数用于回溯搜索
            if board[i][j]!=word[k]:  #当前位置字符不匹配word[k],直接返回False
                return False
            if k==len(word)-1: #如果匹配到了Word的最后一个字符,则返回True,表示找到完整单词
                return True
            #如果 board[i][j] 位置匹配 word[k],则继续搜索。
            visited.add((i,j)) #记录当前位置已访问,防止重复访问
            result=False
            for di,dj in directions:  #判断临界方向的字符
                newi,newj=i+di,j+dj
                if 0<=newi<len(board) and 0<=newj<len(board[0]):# # 确保新的位置在 board 内
                    if (newi,newj)not in visited:  #判断新位置是否被访问过
                        if check(newi,newj,k+1): #递归检查下一个位置
                            result=True
                            break
            visited.remove((i,j))#回溯时,移除当前位置 (i, j),恢复未访问状态
            return result

        h,w=len(board),len(board[0])
        visited=set()
        for i in range(h):
            for j in range(w): #从每个位置 (i, j) 开始搜索
                if check(i,j,0):
                    return True  #只要找到一个匹配的单词,就返回 True
        return False
        

时间复杂度:O(MN⋅3**L),其中 M,N 为网格的长度与宽度,L 为字符串 word 的长度。

空间复杂度:O(MN)。额外开辟了 O(MN) 的 visited 数组

源自力扣官方题解