面试题12:矩阵中的路径

剑指 Offer 12. 矩阵中的路径

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

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

例如,在下面的 3×4 的矩阵中包含单词 "ABCCED"(单词中的字母已标出)。

 

示例 1:

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

输入:board = [["a","b"],["c","d"]], word = "abcd"
输出:false

提示:

1 <= board.length <= 200
1 <= board[i].length <= 200
board 和 word 仅由大小写英文字母组成

这道题考察的是回溯法,就是一种暴力搜索,在到达某一个步骤之后,遍历这一步骤的每一个可能,如果不行就退回之前的步骤继续,,思想比较敏锐的话瞬间就可以发现这里有递归的味道了。

要用递归来解题,就要找到递归的二要素:

1. 递归参数:如果是这道题,每一个小问题就是这个点上下左右有没有符合条件的值,所以条件肯定是是这个点的坐标以及下一步要拟合的字符;

2. 终止条件/出口条件:行或者列越界,当前矩阵元素和需要匹配的元素不合,当前矩阵元素已经访问过,字符串已经全部匹配

所以这道题的递归函数应该是这个:

def dfs(i,j,k):
    # 递归的出口条件:不能越界,不能不相等
    if not 0 <= i <len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: 
        return False
    # 出口条件2,已经全部匹配
    if k == len(word) - 1: 
        return True
    # 将已经访问过的位置元素置空,标记过已经访问
    board[i][j] = ""
    # 递归
    res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
    # 返回时需要还原到初始值
    board[i][j] = word[k]
    return res

题目中给的二维数组大小时大于等于1的,没有特殊情况判断,所以调用这个递归函数用到两层循环就好

所以最终的解是这个:

class Solution(object):
    def exist(self, board, word):
        """
        :type board: List[List[str]]
        :type word: str
        :rtype: bool
        """
        def dfs(i,j,k):
            # 递归的出口条件:不能越界,不能不相等
            if not 0 <= i <len(board) or not 0 <= j < len(board[0]) or board[i][j] != word[k]: 
                return False
            # 出口条件2,已经全部匹配
            if k == len(word) - 1: 
                return True
            # 将已经访问过的位置元素置空,标记过已经访问
            board[i][j] = ""
            # 递归
            res = dfs(i + 1, j, k + 1) or dfs(i - 1, j, k + 1) or dfs(i, j + 1, k + 1) or dfs(i, j - 1, k + 1)
            # 返回时需要还原到初始值
            board[i][j] = word[k]
            return res
        for i in range(len(board)):
            for j in range(len(board[0])):
                if dfs(i, j, 0): 
                    return True
        return False

作者之所以说这道题,更多的是想说明回溯法这种方法,理解之后对于相应的题目就会有相应的思路去解决,这里只是书里的第二章,后面还有更多的算法题对应这种思路。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值