01矩陣
給定一個由 0 和 1 組成的矩陣 mat ,請輸出一個大小相同的矩陣,其中每一個格子是 mat 中對應位置元素到最近的 0 的距離。
兩個相鄰元素間的距離為 1
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL1EFRONTTE50MNpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnLkVGN5QWY4gzNklDNlZWM5YzNyQDN1EmM5U2MkJWM3AzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
最短路徑 采用廣度優先搜尋BFS。如果采用周遊每一個 1,然後進行廣度優先搜尋,時間複雜度過大。這不是單源最短路問題。
是以采用從所有0開始搜尋,像廣播一樣。
多源廣度優先搜尋 可以添加 超級源點轉化為我們平時熟悉的單源 廣度優先搜尋。
- 從超級源點出發
- 同時到達矩陣中所有的0
-
從所有的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