1. 程式人生 > >劍指Offer 65. 矩陣中的路徑 (回溯)

劍指Offer 65. 矩陣中的路徑 (回溯)

題目描述

請設計一個函式,用來判斷在一個矩陣中是否存在一條包含某字串所有字元的路徑。路徑可以從矩陣中的任意一個格子開始,每一步可以在矩陣中向左,向右,向上,向下移動一個格子。如果一條路徑經過了矩陣中的某一個格子,則之後不能再次進入這個格子。 例如 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)