leetcode542 01 矩阵求最短路径

通过动态规划,从四个方向进行状态转移。

class Solution:
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        dp=[[10000 for _ in range(len(matrix[0]))] for _ in range(len(matrix))]
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):  
                if matrix[i][j]==0:
                    dp[i][j]=0    

        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if i-1>=0:
                    dp[i][j]=min(dp[i-1][j]+1,dp[i][j])
                if j-1>=0:
                    dp[i][j]=min(dp[i][j-1]+1,dp[i][j])

        for i in range(len(matrix)-1,-1,-1):
            for j in range(len(matrix[0])-1,-1,-1):
                if i+1<len(matrix):
                   dp[i][j]=min(dp[i+1][j]+1,dp[i][j])
                if j+1<len(matrix[0]):
                    dp[i][j]=min(dp[i][j],dp[i][j+1]+1)

        for i in range(len(matrix)):
            for j in range(len(matrix[0])-1,-1,-1):
                if i-1>=0:
                   dp[i][j]=min(dp[i-1][j]+1,dp[i][j])
                if j+1<len(matrix[0]):
                    dp[i][j]=min(dp[i][j],dp[i][j+1]+1)

        for i in range(len(matrix)-1,-1,-1):
            for j in range(len(matrix[0])):
                if i+1<len(matrix):
                   dp[i][j]=min(dp[i+1][j]+1,dp[i][j])
                if j-1>=0:
                    dp[i][j]=min(dp[i][j],dp[i][j-1]+1)

        return dp

然后发现从两个方向遍历就可以,左下和右上,向右向下的移动,和向左向上的移动。

class Solution:
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        dp=[[10000 for _ in range(len(matrix[0]))] for _ in range(len(matrix))]
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):  
                if matrix[i][j]==0:
                    dp[i][j]=0    


        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if i-1>=0:
                    dp[i][j]=min(dp[i-1][j]+1,dp[i][j])
                if j-1>=0:
                    dp[i][j]=min(dp[i][j-1]+1,dp[i][j])

        for i in range(len(matrix)-1,-1,-1):
            for j in range(len(matrix[0])-1,-1,-1):
                if i+1<len(matrix):
                   dp[i][j]=min(dp[i+1][j]+1,dp[i][j])
                if j+1<len(matrix[0]):
                    dp[i][j]=min(dp[i][j],dp[i][j+1]+1)


        return dp

在一个图中,能从一个点出发求这种最短距离的方法很容易想到就是 BFS,BFS 的名称是广度优先遍历,即把周围这一圈搜索完成之后,再搜索下一圈,是慢慢扩大搜索范围的。

作者:fuxuemingzhu
链接:https://leetcode-cn.com/problems/01-matrix/solution/tao-lu-da-jie-mi-gao-dong-ti-mu-kao-cha-shi-yao-2/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

注意:
求图中的最短路径选择BFS算法
是一圈一圈的搜索,当满足条件了就把距离输出。
每次步数加1是在每一圈结束,每一圈整体会加一步
使用visit数组记录,不要用(x,y)in visit判断这样会浪费很多时间
求1到0的距离时,这种多源的题要反过来,求0到1的最短,入队0元素,求到1的最短距离。
如果将1入队,求得是与1最近的0,这里的问题也是超级源点的问题,如果矩阵中只有一个0,那么1到0的距离就要从0开始进行计算,但是现在的问题是有多个0,那么就是把多个0看作有一个超级源点链接。
图片说明
见题解 https://leetcode-cn.com/problems/01-matrix/solution/01ju-zhen-by-leetcode-solution/

class Solution:
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        queue=collections.deque()
        directions=[(0,1),(1,0),(-1,0),(0,-1)]
        result=[[0 for _ in range(len(matrix[0]))] for _ in range(len(matrix))]
        visit=[[0]*len(matrix[0]) for _ in range(len(matrix))]
        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j]==0:
                    queue.append((i,j))
                    visit[i][j]=1
        step=0

        while queue:
            size=len(queue)
            for i in range(size):
                x,y=queue.popleft()

                if matrix[x][y]==1:
                    result[x][y]=step

                for item in directions:
                    if x+item[0]<len(matrix) and x+item[0]>=0 and y+item[1]<len(matrix[0]) and y+item[1]>=0 and  visit[x+item[0]][y+item[1]]!=1 :

                        queue.append((x+item[0],y+item[1]))
                        visit[x+item[0]][y+item[1]]=1
                    else:
                        continue

            step+=1
        return result

同样可以通过matrix数组本身得到结果,这样需要matrix中的1的位置替换成-1 来标识未访问节点。
也可以通过result数组result[x][y]+=1得到结果,这样的话就不用每次for循环遍历队列当前长度,来控制这次的遍历整体移动一步了。

class Solution:
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        queue=collections.deque()

        directions=[(0,1),(1,0),(-1,0),(0,-1)]

        result=[[0 for _ in range(len(matrix[0]))] for _ in range(len(matrix))]


        for i in range(len(matrix)):
            for j in range(len(matrix[0])):
                if matrix[i][j]==0:
                    queue.append((i,j))
                else:
                    matrix[i][j]=-1


        while queue:

                x,y=queue.popleft()

                # if matrix[x][y]==1:
                #     result[x][y]=step

                for item in directions:
                    if x+item[0]<len(matrix) and x+item[0]>=0 and y+item[1]<len(matrix[0]) and y+item[1]>=0 and  matrix[x+item[0]][y+item[1]]==-1 :

                        matrix[x+item[0]][y+item[1]]=matrix[x][y]+1
                        queue.append((x+item[0],y+item[1]))


        return matrix
全部评论

相关推荐

11-17 11:15
门头沟学院 Java
金山办公终于发offer了,但薪资和平台都不如已有的offer打算拒了,A不了薪资,不满意直接拒了,留给需要的人嘿嘿嘿时间线:10.14线下一面&nbsp;,10.23线上二面,下午发测评,11月1日HR面,11月14日电话谈薪,11月17日直接发offer
star__plat...:好兄弟干的好啊,解气。金山第一次笔难度高的离谱,第二次简单的离谱全A了,用人部门筛选中估计最后还是要挂我,就这今早智联招聘还给我发信息让我投
offer帮选
点赞 评论 收藏
分享
10-13 16:58
门头沟学院 Java
点赞 评论 收藏
分享
双尔:你就写拥有ai开发经历,熟练运用提示词,优化ai,提高ai回答质量
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务