剑指offer 12 - 矩阵中的路径 - python

270 阅读2分钟

题目描述:

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 [ a b c e s f c s a d e e ] \begin{bmatrix} a & b & c &e \\ s & f & c & s \\ a & d & e& e\\ \end{bmatrix}\quad ⎣⎡​asa​bfd​cce​ese​⎦⎤​矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
示例 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

思路

首先分析题意,题目给定了一个二维矩阵,其中每个位置的元素都是唯一的。我们想要做的是要找到一条路径使得路径上的字符组成的字符串等于给定的字符串。而且寻找路径的过程中可以向上、向下、向左和向右四种走法,但是当前路径上已经被访问过的元素就不能被访问了。

因此,我们需要使用回溯 + 深搜来寻找路径,如果从某个可能的起点的某个方向开始寻找路径无果,那么就要回溯到开始的位置从其他的方向继续寻找。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        if not board: return False

        rows, cols = len(board), len(board[0])
        vis = [[False] * cols for i in range(rows)] # 创建一个访问矩阵,标识指定位置的元素是否被访问
		
		# 回溯 +  深搜
        def dfs(board, row, col, vis, path):
        	# 如果word中每一个字符都已经被匹配,说明找到了路径,直接返回True
            if not path: return True
			# 边界条件
            if row < 0 or row >= rows or col < 0 or col >= cols or board[row][col] != path[0] or vis[row][col] == True:
                return False
			
			# 做选择
            vis[row][col] = True
            # 考虑所有可能的情况,只要有满足情况的路径就返回True
            # 向上 row - 1, col
            # 向下 row + 1, col
            # 向左 row, col - 1
            # 向右 row , col + 1
            if dfs(board, row + 1, col, vis, path[1:]) 
            	or dfs(board, row, col + 1, vis, path[1:]) 
            	or dfs(board, row - 1, col, vis, path[1:]) 
            	or dfs(board, row, col - 1, vis, path[1:]):
                return True
			# 撤销选择
            vis[row][col] = False

            return False


        for row in range(rows):
            for col in range(cols):
                if dfs(board, row, col, vis, word):
                    return True
                    break
        
        return False