在 LeetCode 问题上获得 Enclave 数量的 TLE
我遇到了LeetCode问题1020。飞地数量:
给你一个
mx n
二进制矩阵grid
, 其中0
代表海洋单元,1
代表陆地单元。 移动包括从一个陆地单元步行到另一个相邻的单元 (4 向)陆地单元或走出网格
的边界。返回网格中我们无法行走的陆地单元的数量 在任意次数的移动中离开网格边界。
示例 1:
输入:
grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0 ,0,0,0]]
输出:3
解释:有 3 个 1 被 0 包围, 和一个未封闭的 1,因为它位于边界上。示例 2:
输入:
grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0 ,0,0,0]]
输出:0
解释:所有 1 要么在边界上,要么可以到达 边界。
我使用 BFS 构建了以下解决方案
class Solution(object):
def numEnclaves(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
stack = []
visited = set()
row_0 = grid[0]
row_n = grid[-1]
col_0 = [row[0] for row in grid]
col_n = [row[-1] for row in grid]
num_rows = len(grid)
num_cols = len(grid[0])
for col, val in enumerate(row_0):
if val == 1:
stack.append([0, col])
visited.add((0, col))
for col,val in enumerate(row_n):
if val == 1:
stack.append([num_rows-1, col])
visited.add((num_rows-1, col))
for row, val in enumerate(col_0):
if val == 1:
stack.append([row, 0])
visited.add((row, 0))
for row, val in enumerate(col_n):
if val == 1:
stack.append([row, num_cols -1])
visited.add((row, num_cols -1))
while stack:
row, col = stack.pop(0)
visited.add((row, col))
steps = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for _row, _col in steps:
_row += row
_col += col
if _row <0 or _row > num_rows -1:
continue
if _col <0 or _col > num_cols -1:
continue
if (_row, _col) in visited:
continue
if grid[_row][_col] == 1:
stack.append([_row, _col])
result = 0
for row in range(1, num_rows-1):
for col in range(1, num_cols -1):
if grid[row][col] == 1 and (row,col) not in visited:
result += 1
return result
我的解决方案对于较小的输入工作正常,但对于较大的值(例如:大小为 200x200 的网格)则失败。我无法理解解决方案中可能导致 TLE 的原因,或者如何进一步优化它?
I encountered the LeetCode problem 1020. Number of Enclaves:
You are given an
m x n
binary matrixgrid
,
where0
represents a sea cell and1
represents a land cell.
A move consists of walking from one land cell to another adjacent
(4-directionally) land cell or walking off the boundary of thegrid
.Return the number of land cells in
grid
for which we cannot walk
off the boundary of the grid in any number of moves.Example 1:
Input:
grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
Output:3
Explanation: There are three 1s that are enclosed by 0s,
and one 1 that is not enclosed because its on the boundary.Example 2:
Input:
grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
Output:0
Explanation: All 1s are either on the boundary or can reach the
boundary.
I built the following solution using BFS
class Solution(object):
def numEnclaves(self, grid):
"""
:type grid: List[List[int]]
:rtype: int
"""
stack = []
visited = set()
row_0 = grid[0]
row_n = grid[-1]
col_0 = [row[0] for row in grid]
col_n = [row[-1] for row in grid]
num_rows = len(grid)
num_cols = len(grid[0])
for col, val in enumerate(row_0):
if val == 1:
stack.append([0, col])
visited.add((0, col))
for col,val in enumerate(row_n):
if val == 1:
stack.append([num_rows-1, col])
visited.add((num_rows-1, col))
for row, val in enumerate(col_0):
if val == 1:
stack.append([row, 0])
visited.add((row, 0))
for row, val in enumerate(col_n):
if val == 1:
stack.append([row, num_cols -1])
visited.add((row, num_cols -1))
while stack:
row, col = stack.pop(0)
visited.add((row, col))
steps = [[1, 0], [-1, 0], [0, 1], [0, -1]]
for _row, _col in steps:
_row += row
_col += col
if _row <0 or _row > num_rows -1:
continue
if _col <0 or _col > num_cols -1:
continue
if (_row, _col) in visited:
continue
if grid[_row][_col] == 1:
stack.append([_row, _col])
result = 0
for row in range(1, num_rows-1):
for col in range(1, num_cols -1):
if grid[row][col] == 1 and (row,col) not in visited:
result += 1
return result
My solution works fine for smaller inputs, however it fails for larger values ex: a grid of size 200x200. I fail to understand what might be causing the TLE in the solution, or how I can optimise it further?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的解决方案是使用一个集合来查找节点是否被访问过 - 但这不是必需的,因为您可以简单地在节点上放置一个标记来表示您访问过它。例如,假设
2
代表从现在开始访问:时间急剧下降,并且您在问题中给出的测试仍然通过。您应该知道,如果集合大小非常大,则集合访问实际上并不是
O(1)
。Your solution is using a set in order to find if a node was visited - but this is not necessary since you can simply put a marker on the node saying you visited it. For example let's say
2
stands for visited from now on:The time drops dramatically and the tests you gave in the question still passes. You should know that a set access is not really
O(1)
if the set size is very big.主要问题是,当您将单元格放入堆栈(实际上是一个队列)时,您不会将单元格标记为已访问。这意味着堆栈将具有重复的单元,从而减慢该过程。
正如其他人提到的,您可以使用网格本身将单元格标记为已访问,但我只会删除您访问的 1(为 0)。最后,您只需对所有单元格值进行求和即可。
其他一些事情:
steps
一次,不在循环内;sum
得到最终的计数;建议的代码:
The main issue is that you do not mark cells as visited the moment you put them on
stack
(which really is a queue). This means that the stack will have duplicate cells, which slows down the process.As mentioned by others, you can use the grid itself for marking cells as visited, but I would just wipe out the 1 that you visit (to 0). Then at the end you only need to sum all cell values.
Some other things:
steps
once, not inside the loop;sum
to get the final count;Suggested code: