zoukankan      html  css  js  c++  java
  • 【LeetCode】面试题12. 矩阵中的路径

    题目:

    思路:

    因为可以从矩阵中任意一格开始,所以拿到题之后的思路为: 遍历整个矩阵,尝试把每个点当作起始点去搜索路径,直到找到或者遍历完。考虑到有点暴力,感觉不是最优方法,所以一直在思考更优的方法(也被它动态规划的标签误导了),陷入了瓶颈,没有把之前的暴力思路抽象到深度优先搜索的方法论。
    另外一直在把思路复杂化,考虑记录每次进入某个节点的方向,避免形成循环。而参考了代码中的思路之后,将当前值置为"/",避免了循环。从而能够抽象到特别简单的DFS中,只需要考虑边界就可以了,避免了复杂的条件判断。
    也想到了另一个方法: 对整个矩阵遍历K轮,第k轮遍历找到矩阵中等于目标字符串位置k的字符,查看该位置的上下左右,是否已经组成了前k-1个目标字符串,需要注意的点有: 避免循环,到达某个点的路径可能有多条,都需要记录下来。

    代码:

    Python

    # Solution1 84/87超时
    # [["A","B","C","E"],["S","F","E","S"],["A","D","E","E"]] "ABCESEEEFS"
    # [["a"]] "a"
    # [["a", "a"], ["a", "a"]]  "aaaaa"
    import copy
    class Solution(object):
        def exist(self, board, word):
            """
            :type board: List[List[str]]
            :type word: str
            :rtype: bool
            """
            x = len(board)
            y = len(board[0])
            # 构造now记录每个位置的当前路径[[[set(), set()], []], [[], []]]
            # 每个点通过一个list记录,有几条路径list中就有几个元素,每个元素是set,保证路径不重复
            # 构造过程也是第一个目标字符的遍历过程
            now = list()
            for i in range(x):
                tmp = list()
                for j in range(y):
                    if board[i][j] == word[0]:  # 目标字符串长度为1的情况
                        if len(word) == 1:
                            return True
                        # 保证是list(set(tuple))结构
                        a = set()
                        a.add((i, j))
                        tt = list()
                        tt.append(a)
                        tmp.append(tt)
                    else:
                        tmp.append(list())
                now.append(tmp)
            # 遍历剩余目标字符
            for c in range(1, len(word)):
                # 因为会修改now,避免修改后的now被用于当前轮次
                pre = copy.deepcopy(now)
                this_char = word[c]
                for i in range(x):
                    for j in range(y):
                        now[i][j] = list()
                        # 遍历整个矩阵,对等于当前目标字符的位置。查看它的上下左右,是否存在长度为c的前缀路径,把它们全部找出来
                        if board[i][j] == this_char:
                            pre_list = list()
                            if i - 1 >= 0 and len(pre[i-1][j]) > 0:
                                pre_list.extend(pre[i-1][j])
                            if j - 1 >= 0  and len(pre[i][j-1]) > 0:
                                pre_list.extend(pre[i][j-1])
                            if i + 1 < x and len(pre[i+1][j]) > 0:
                                pre_list.extend(pre[i+1][j])
                            if j + 1 < y and len(pre[i][j+1]) > 0:
                                pre_list.extend(pre[i][j+1])
                            # 对每一个前缀路径,添加当前节点
                            # 如果重复则整个前缀路径失效,判断是否找到
                            for e in pre_list:
                                ee = copy.deepcopy(e)  # 这里不copy会修改pre的数据??
                                ee.add((i, j))
                                if len(ee) == len(word):
                                    return True
                                if len(ee) == (c+1):
                                    now[i][j].append(ee)
            return False
    
    # Solution2
    class Solution(object):
        def exist(self, board, word):
            """
            :type board: List[List[str]]
            :type word: str
            :rtype: 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
    

    相关问题

  • 相关阅读:
    pytorch图像处理的问题
    MWCNN中使用的haar小波变换 pytorch
    GhostNet: More Features from Cheap Operations
    人脸检测和识别以及检测中loss学习
    人脸检测和识别以及检测中loss学习
    C++ string的find类函数的使用
    pytorch各个版本的.whl文件下载地址
    人脸识别和检测中loss学习
    人脸识别和检测中loss学习
    人脸识别和检测中错误数据的三种类别
  • 原文地址:https://www.cnblogs.com/cling-cling/p/12956930.html
Copyright © 2011-2022 走看看