多源最短路径

01矩阵
给定一个由 0 和 1 组成的矩阵 mat ,请输出一个大小相同的矩阵,其中每一个格子是 mat 中对应位置元素到最近的 0 的距离。
两个相邻元素间的距离为 1

在这里插入图片描述
最短路径 采用广度优先搜索BFS。如果采用遍历每一个 1,然后进行广度优先搜索,时间复杂度过大。这不是单源最短路问题。

因此采用从所有0开始搜索,像广播一样。
多源广度优先搜索 可以添加 超级源点转化为我们平时熟悉的单源 广度优先搜索。在这里插入图片描述

  1. 从超级源点出发
  2. 同时到达矩阵中所有的0
  3. 从所有的0开始向上下左右四个邻居扩展。
    其实多源广度优先搜索就相当于单源广度优先搜索的第二步。

首先
初始化一个新的矩阵mat2,遍历mat矩阵,若为0,mat2相应的位置置为0,同时入队列queue。(入队列的为位置下标)若为1,mat2相应的位置置为max。

queue = []
mat2 = []
for i in range(len(mat)):
	mat2.append([])
    for j in range(len(mat[i])):
        if mat[i][j] == 0:
             mat2[i].append(0)
             queue.append((i,j))
        else:
             mat2[i].append(100000)
             

然后
就和单源广度优先搜索一样进行遍历

oris = ((0,-1),(0,1),(-1,0),(1,0))
while len(queue)>0:
	r,c = queue[0];queue.pop(0)
    for ori in oris:
		new_r = r+ori[0];new_c = c+ori[1]
		if new_c>=0 and new_c<len(mat[0]) and new_r>=0 and new_r<len(mat):
			if mat2[new_r][new_c] > mat2[r][c]+1:
				mat2[new_r][new_c] = mat2[r][c]+1
				queue.append((new_r,new_c))

每次出队一个元素(mat2[r][c]),如果其上下左右四个方向的某一方向(mat2[new_r][new_c])的元素 比该出队的元素加1 大,则这一方向的元素赋值为 mat2[r][c]+1。并入队。

完整代码为:

class Solution:
    def updateMatrix(self, mat: list[list[int]]) -> list[list[int]]:
        queue = []
        mat2 = []
        for i in range(len(mat)):
            mat2.append([])
            for j in range(len(mat[i])):
                if mat[i][j] == 0:
                    mat2[i].append(0)
                    queue.append((i,j))
                else:
                    mat2[i].append(100000)

        oris = ((0,-1),(0,1),(-1,0),(1,0))
        while len(queue)>0:
            r,c = queue[0];queue.pop(0)
            for ori in oris:
                new_r = r+ori[0];new_c = c+ori[1]
                if new_c>=0 and new_c<len(mat[0]) and new_r>=0 and new_r<len(mat):
                    # print(f"new_r:{new_r},new_c:{new_c}")
                    if mat2[new_r][new_c] > mat2[r][c]+1:
                        mat2[new_r][new_c] = mat2[r][c]+1
                        queue.append((new_r,new_c))

        return mat2

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值