《剑指offer》11、矩阵路径(回溯法)

矩阵路径

offer11将给出一个字符矩阵以及一个“路径”,试问矩阵中是否存在这样的一个路径。以下面的一个矩阵为例,它存在路径REALITY,但不存在路径FAKE:

回溯法

这里必然涉及简单的回溯法解题了。回溯法是一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。它是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
这里借别人一张图:

分析

只有文字和伪代码可能还有所欠缺,我们再以REALITY和FAKE的搜索为例子:

REALITY的路径搜索

先遍历矩阵,找到位于第一排的R
→ 检查边界条件,R可以向三个方向搜索E,找到R下方的E
→ 标记R,此时E可以向左右下三个方向搜索A,找到E左边的A
→ 标记A,此时A可以向左上下三个方向搜索L,找到A左边的L
→ 标记L,此时L可以向上下两个方向搜索I,找到L下方的I
→ 标记I,此时I可以向右下两个方向搜索T,但是都没搜到→回到上一步的L
→ 在L的另外两个方向没有搜索到I,回到上一步的A→回到上一步的E→找到E右边的A
→ 以此类推,找到REALITY
(如果还没找到,还要对第三排的R进行相同的操作,实际上该例有2条路径)

我们可以注意到,在RE后的第一个分岔路口,我们先是向左深搜,直到走到尽头后再回头,然后再向右找到正解,这就是回溯。

FAKE的路径搜索

和REALITY的路径搜索类似,从第一排的F开始
→ 可以看到,F到A到K以后,因为没有E,所以向上回溯
→ 而A的周围只有一个K,F的周围只有一个A,回溯结束,return False

代码

这里仿照了一个大佬的代码。我第一次写得像bullsh*t,实在难登大雅之堂。思路和注释都写在代码上面了。

# offer11-solution
class Solution:

    def MatrixPath(self, matrix, rows, cols, path):  # 输入矩阵,行数,列数,路径
        if not matrix or rows < 0 or cols < 0 or path == None:
            return False
        markmatrix = [0]*(rows*cols)
        pathIndex = 0
        for row in range(rows):
            for col in range(cols):  # 遍历找字符串中第一个字母
                if self.MatrixPathCore(matrix, rows, cols, row, col, path, pathIndex, markmatrix):
                    return True
        return False

    def MatrixPathCore(self, matrix, rows, cols, row, col, path, pathIndex, markmatrix):
        if pathIndex == len(path):  # 最后一个index恰好能对应
            return True
        hasPath = False
        # 不在边界条件上,且字符刚好能对应
        if row >= 0 and row < rows and col >= 0 and col < cols and matrix[row*cols+col] == path[pathIndex] and not markmatrix[row * cols + col]:
            pathIndex += 1  # index后移
            markmatrix[row*cols+col] = True  # 找到了,赋值为T,下面从四个方向进行回溯法
            hasPath = self.MatrixPathCore(matrix, rows, cols, row+1, col, path, pathIndex, markmatrix) or \
                      self.MatrixPathCore(matrix, rows, cols, row-1, col, path, pathIndex, markmatrix) or \
                      self.MatrixPathCore(matrix, rows, cols, row, col+1, path, pathIndex, markmatrix) or \
                      self.MatrixPathCore(matrix, rows, cols, row, col-1, path, pathIndex, markmatrix)
            if not hasPath:
                pathIndex -= 1
                markmatrix[row * cols + col] = False
        return hasPath

参考

回溯法–深度优先搜索
021-回溯法与深搜的关系-《算法设计技巧与分析》M.H.A学习笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值