【发布时间】:2022-01-17 12:35:03
【问题描述】:
对于 leetcode 200 Number of Islands,这个解决方案可以正常工作。但是,对于较低的解决方案,由于超出时间限制,提交失败。据我了解,两种解决方案都应该同时运行。你能帮忙吗?
class Solution {
// BFS time O(mn) | space O(min(m,n))
public int numIslands(char[][] grid) {
int islandsCount = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
islandsCount++;
bfs(grid, i, j);
}
}
}
return islandsCount;
}
public static void bfs(char[][] grid, int row, int col) {
int rc = grid.length;
int cc = grid[0].length;
Deque<Integer> queue = new ArrayDeque<Integer>();
queue.offer(row*cc + col);
while (!queue.isEmpty()) {
Integer spotIdx = queue.poll();
int i = spotIdx/cc, j = spotIdx%cc;
// grid[i][j] = '0';
if (i-1 >= 0 && grid[i-1][j] == '1') {
queue.offer((i-1)*cc+j);
grid[i-1][j] = '0';
}
if (i+1 < rc && grid[i+1][j] == '1') {
queue.offer((i+1)*cc+j);
grid[i+1][j] = '0';
}
if (j-1 >= 0 && grid[i][j-1] == '1') {
queue.offer(i*cc+(j-1));
grid[i][j-1] = '0';
}
if (j+1 < cc && grid[i][j+1] == '1') {
queue.offer(i*cc+(j+1));
grid[i][j+1] = '0';
}
}
return;
}
}
以下版本会抛出超过时间限制,但在某些测试用例中仍然给出正确答案。
class Solution {
// BFS time O(mn) | space O(min(m,n))
public int numIslands(char[][] grid) {
int islandsCount = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '1') {
islandsCount++;
bfs(grid, i, j);
}
}
}
return islandsCount;
}
public static void bfs(char[][] grid, int row, int col) {
int rc = grid.length;
int cc = grid[0].length;
Deque<Integer> queue = new ArrayDeque<Integer>();
queue.offer(row*cc + col);
while (!queue.isEmpty()) {
Integer spotIdx = queue.poll();
int i = spotIdx/cc, j = spotIdx%cc;
grid[i][j] = '0';
if (i-1 >= 0 && grid[i-1][j] == '1') {
queue.offer((i-1)*cc+j);
}
if (i+1 < rc && grid[i+1][j] == '1') {
queue.offer((i+1)*cc+j);
}
if (j-1 >= 0 && grid[i][j-1] == '1') {
queue.offer(i*cc+(j-1));
}
if (j+1 < cc && grid[i][j+1] == '1') {
queue.offer(i*cc+(j+1));
}
}
return;
}
}
【问题讨论】:
-
第一个代码将网格元素写入队列时将其标记为已访问。当它们从队列中读取时,第二个代码将它们标记为已访问。所以问题是在第二个代码中,同一个元素可以多次写入队列。证明这一点的简单方法是添加一个
int q_count变量,该变量在每次调用queue.offer时递增。然后在 BFS 完成后打印计数。
标签: java algorithm time-complexity breadth-first-search