剑指Offer 65. 矩阵中的路径 (回溯)

Posted on 2018-10-18 11:06  _hqc  阅读(254)  评论(0编辑  收藏  举报

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

题目地址

https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&rp=3&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

思路

回溯法解决

首先,遍历这个矩阵,我们很容易就能找到与字符串str中第一个字符相同的矩阵元素ch。然后遍历ch的上下左右四个字符,如果有和字符串str中下一个字符相同的,就把那个字符当作下一个字符(下一次遍历的起点),如果没有,就需要回退到上一个字符,然后重新遍历。为了避免路径重叠,需要一个辅助矩阵来记录路径情况。

下面代码中,当矩阵坐标为(row,col)的格子和路径字符串中下标为pathLength的字符一样时,从4个相邻的格子(row,col-1)、(row-1,col)、(row,col+1)以及(row+1,col)中去定位路径字符串中下标为pathLength+1的字符。

如果4个相邻的格子都没有匹配字符串中下标为pathLength+1的字符,表明当前路径字符串中下标为pathLength的字符在矩阵中的定位不正确,我们需要回到前一个字符串(pathLength-1),然后重新定位。

Python

# -*- coding:utf-8 -*-
class Solution:
    def hasPath(self, matrix, rows, cols, path):
        # write code here
        if not matrix or rows < 1 or cols < 1 or not path:
            return False
        visited = [False] * len(matrix)
        pathLength =[0]
        for i in range(rows):
            for j in range(cols):
                # 以矩阵中的每一个位置作为起点进行搜索
                if self.Path(matrix,rows,cols,path,j,i,visited,pathLength):
                    return True
        return False

    def Path(self,matrix,rows,cols,path,x,y,visited,pathLength):
        if pathLength[0] == len(path):
            return True
        curHasPath = False
        # 位置坐标不超过行列数,当前位置字符等于路径中对应位置的字符,当前位置没有在已找到的路径中
        if 0<=x<cols and 0<=y<rows and matrix[y*cols+x]==path[pathLength[0]] and not visited[y*cols+x]:
            visited[y*cols+x] = True
            pathLength[0]+=1
            curHasPath = self.Path(matrix, rows, cols, path, x + 1, y, visited, pathLength) or \
                         self.Path(matrix, rows, cols, path, x - 1, y, visited, pathLength) or \
                         self.Path(matrix, rows, cols, path, x, y + 1, visited, pathLength) or \
                         self.Path(matrix, rows, cols, path, x, y - 1, visited, pathLength)
            if not curHasPath:
                pathLength[0] -= 1
                visited[y*cols+x] = False
        return curHasPath
if __name__ == '__main__':
    result = Solution().hasPath("ABCESFCSADEE",3,4,"SEE")
    print(result)