英文:
Why my code is giving TLE while a similar implementation passes (BFS)?
问题
I am solving this question. I am implementing BFS, and my implementation is as follows:
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
if grid[0][0] == 1:
return -1
M=len(grid)-1
seen = set()
q = deque([])
res = float('inf')
q.append((0,0,1))
while q:
r,c, curr = q.popleft()
if r==M and c==M:
return curr
directions = [[1,0], [0,1], [1,1], [-1,0], [0,-1], [-1,-1], [1, -1], [-1, 1]]
seen.add((r,c))
for ro, co in directions:
nr, nc = r+ro, c+co
if (nr,nc) in seen or nr < 0 or nc < 0 or nr > M or nc > M or grid[nr][nc] == 1:
continue
q.append((nr,nc,curr+1))
return -1
but this gives TLE for large input. However, a similar implementation passes:
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
N = len(grid)
q = deque([(0, 0, 1)]) # r, c, length
visit = set((0, 0))
direct = [[0, 1], [1, 0], [0, -1], [-1, 0],
[1, 1], [-1, -1], [1, -1], [-1, 1]]
while q:
r, c, length = q.popleft()
if (min(r, c) < 0 or max(r, c) >= N or grid[r][c]):
continue
if r == N - 1 and c == N - 1:
return length
for dr, dc in direct:
if (r + dr, c + dc) not in visit:
q.append((r + dr, c + dc, length + 1))
visit add((r + dr, c + dc))
return -1
What is slowing my code down?
I am unable to understand why my code is slower.
英文:
I am solving this question. I am implementing BFS and my implementation is as follows:
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
if grid[0][0] == 1:
return -1
M=len(grid)-1
seen = set()
q = deque([])
res = float('inf')
q.append((0,0,1))
while q:
r,c, curr = q.popleft()
if r==M and c==M:
return curr
directions = [[1,0], [0,1], [1,1], [-1,0], [0,-1], [-1,-1], [1, -1], [-1, 1]]
seen.add((r,c))
for ro, co in directions:
nr, nc = r+ro, c+co
if (nr,nc) in seen or nr < 0 or nc < 0 or nr > M or nc > M or grid[nr][nc] == 1:
continue
q.append((nr,nc,curr+1))
return -1
but this gives TLE for large input. However, a similar implementation passes:
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
N = len(grid)
q = deque([(0, 0, 1)]) # r, c, length
visit = set((0, 0))
direct = [[0, 1], [1, 0], [0, -1], [-1, 0],
[1, 1], [-1, -1], [1, -1], [-1, 1]]
while q:
r, c, length = q.popleft()
if (min(r, c) < 0 or max(r, c) >= N or
grid[r][c]):
continue
if r == N - 1 and c == N - 1:
return length
for dr, dc in direct:
if (r + dr, c + dc) not in visit:
q.append((r + dr, c + dc, length + 1))
visit.add((r + dr, c + dc))
return -1
What is slowing my code down?
I am unable to understand why my code is slower.
答案1
得分: 1
您的解决方案只需进行两个小的更改就能通过。
主要更改在于将将已访问的单元格添加到 seen
的代码移到了与新单元格添加到队列的代码相同的级别。
原始代码的缺点是,当重复的单元格在相同的BFS级别上添加到队列时,它无法避免重复,因为 seen
不会随着队列的更新而更新。
将 seen
的更新移到与队列的更新在同一级别上确保了仅有独特的单元格会被添加到下一级BFS的队列中。
英文:
You solution would pass with just two small changes.
class Solution:
def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:
if grid[0][0] == 1:
return -1
M=len(grid)-1
seen = set([(0,0)]) # <-- initialize with (0, 0)
q = deque([])
res = float('inf')
q.append((0,0,1))
while q:
r,c, curr = q.popleft()
if r==M and c==M:
return curr
directions = [[1,0], [0,1], [1,1], [-1,0], [0,-1], [-1,-1], [1, -1], [-1, 1]]
for ro, co in directions:
nr, nc = r+ro, c+co
if (nr,nc) in seen or nr < 0 or nc < 0 or nr > M or nc > M or grid[nr][nc] == 1:
continue
q.append((nr,nc,curr+1))
seen.add((nr,nc)) # <-- mark nodes that surely will be visited
return -1
Note that the main change in the logic is that the line to add visited cells to seen
is moved to the same level where new cells are added to the queue.
The drawback of the original code is that it cannot avoid duplication when duplicated cells are added to the queue on the same BFS level, because seen
is not updated along with the queue.
Moving the update of seen
to the same level as the update of queue guarantees that only unique cells are added to the queue for the next level of BFS.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论