剑指offer

面试题12. 矩阵中的路径

2020-03-06  本文已影响0人  人一己千

题目

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一格开始,每一步可以在矩阵中向左、右、上、下移动一格。如果一条路径经过了矩阵的某一格,那么该路径不能再次进入该格子。例如,在下面的3×4的矩阵中包含一条字符串“bfce”的路径(路径中的字母用加粗标出)。

[["a","b","c","e"],
["s","f","c","s"],
["a","d","e","e"]]

但矩阵中不包含字符串“abfb”的路径,因为字符串的第一个字符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

注意:本题与主站 79 题相同:https://leetcode-cn.com/problems/word-search/

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解法

比较简单的回溯,我用了一个表来记录走过的路径,特别注意的是回溯到上一层的时候(函数结束)要还原回去。
还有用了一个全局变量来表示是否找到。

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        self.board = board
        self.word_list = [c for c in word]
        self.length = len(self.word_list)
        self.ans = False

        for i in range(len(self.board)):
            for j in range(len(self.board[0])):
                self.table = [[0]*len(self.board[0]) for _ in range(len(self.board))]
                self.find(i,j,0)
                if self.ans :
                    return True
        return False

    def find(self, i, j, str_index):
        # 判读是否已成
        if self.ans:
            return

        # 边界判断
        if i < 0 or i >= len(self.board) or j < 0 or j >= len(self.board[0]) or self.table[i][j]==1:
            return 

        if self.board[i][j] == self.word_list[str_index] :
            # 可能是对的路
            self.table[i][j] = 1
            str_index += 1
            # 完结
            if str_index == self.length:
                self.ans = True
                return
            # 继续走
            self.find(i+1,j,str_index)
            self.find(i,j+1,str_index)
            self.find(i-1,j,str_index)
            self.find(i,j-1,str_index)
        self.table[i][j] = 0

总结

代码写得比较乱,但是总体思路没有问题。
需要整理。

来自leetcode精选题解的代码:

class Solution:
    def exist(self, board: List[List[str]], word: str) -> 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
            if k == len(word) - 1: return True
            tmp, board[i][j] = 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] = tmp
            return res

        for i in range(len(board)):
            for j in range(len(board[0])):
                if dfs(i, j, 0): return True
        return False

作者:jyd
链接:https://leetcode-cn.com/problems/ju-zhen-zhong-de-lu-jing-lcof/solution/mian-shi-ti-12-ju-zhen-zhong-de-lu-jing-shen-du-yo/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个写得真简洁啊。
用board自身作为路径,不过访问过用'/'标记这个方法,在字符串中本身就有的话就不好使了。

所以根据以上的略改版本:

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        rows = len(board)
        cols= len(board[0])
        table = [[0]*cols for _ in range(rows)]
        def dfs(i,j,index):
            if not 0<=i<rows or not 0<=j<cols or board[i][j] != word[index] or table[i][j] == 1:
                return False
            # 这个容易忘记。。。
            if index == len(word)-1:return True
            table[i][j] = 1
            ans = dfs(i+1,j,index+1) or dfs(i-1,j,index+1) or dfs(i,j+1,index+1) or dfs(i,j-1,index+1)
            table[i][j] = 0
            return ans
上一篇下一篇

猜你喜欢

热点阅读