LeetCode——递归问题——单词搜索

递归问题总结——单词搜索

总结:

  1. 递归问题一般是搜索一个可行解,而非从很多解中找到最优解(动态规划)
  2. 递归是向前的试探搜索,试探搜索过程中有记录状态的变量时,如果当前步not return true,记得记录状态变量的复原
  3. 递归中的return true,只有n=1时,才return true;其他时候满足条件时,则继续搜索,否则进行剪枝,return false。

题目

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

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

示例:

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

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

代码

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        # 1. 需要记录已经走过的位置
        # 2. 判断一步,移动一步
        # 3. 找到初始位置
        
        if len(word) == 0:
            return True
        
        
        self.dir = [[-1,0],[0,-1],[1,0],[0,1]]
        self.row = len(board)
        self.col = len(board[0])
        visited = [[0] * self.col for _ in range(self.row)]
        
        # 第一层循环找开始点
        for i in range(self.row):
            for j in range(self.col):
                if board[i][j] == word[0]:
                    visited = [[0] * self.col for _ in range(self.row)]
                    if self.dfs(word, board, visited, i, j):
                        return True
                    
        return False
    
    # 递归函数
    def dfs(self, word, board, visited, i, j):
        if len(word) == 0:					# 递归的结束条件
            return True
        if len(word) == 1 and word[0] == board[i][j]:
            return True
        
        if word[0] == board[i][j]:          # 如何通过则继续搜索
            visited[i][j] = 1
            # return True		# 千万不能return true,这只是中间一步满足要求
        else:
            return False                    # 剪支

        
        for k in range(4):
            nextx, nexty = i + self.dir[k][0], j + self.dir[k][1]		# 移动一步
            if self.legal(nextx, nexty, visited):
                if self.dfs(word[1:], board, visited, nextx, nexty):
                    return True
                else:
                    visited[nextx][nexty] = 0       # 恢复现场,因为递归是试探性的,所以要恢复一些变量
        
        return False
            
        
    def legal(self, x, y, visited):
    	# 每移动一步的合法性判断
        if 0 <= x < self.row and 0 <= y < self.col and visited[x][y] != 1: 
            # if self.visited[x][y] == 0:
            return True
        else:
            return False

总体流程和注意的细节具体可以看代码注释

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值