如何解决BFS算法不会在Leetcode上的Rotten Oranges问题中标记所有节点
我正在研究rotten oranges problem:
在给定的网格中,每个单元格可以具有以下三个值之一:
- 值0代表一个空单元格;
- 值1代表鲜橙色;
- 值2代表烂橙。
每分钟,任何新鲜的橙子(与4方向相邻) 烂橙变烂了。
返回直到没有单元格之前必须经过的最小分钟数 有一个新鲜的橙子。如果这不可能,请返回-1。
示例1:
- 输入:[[1,1,1],[1,0],[0,2]]
- 输出:4
我已经实现了BFS解决方案。然后,在完成BFS之后,我再次进行迭代以确保没有剩余的新鲜橙子,因为如果剩余了新鲜橙子,那么我必须返回-1。
但是,我发现在最后一个循环中,只有一些值更改为2,而其他一些值仍保持为1。我不确定为什么它们也没有更改为2。
class Solution {
public int orangesRotting(int[][] grid) {
//need adjacency list/matrix
Queue<String> q = new LinkedList<>();
int[] count = new int[1];
count[0] = 0;
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[i].length; j++) {
if(grid[i][j] == 2) {
q.add("" + i + j);
bfs(grid,i,j,count,q);
}
}
}
for(int i = 0; i < grid.length; i++) {
for(int j = 0; j < grid[i].length; j++) {
// does NOT always print correct value: 1 is not changed to 2
System.out.println(grid[i][j]);
if(grid[i][j] == 1) {
return -1; // ... and so this -1 is returned when it shouldn't
}
}
}
return count[0];
}
private static void bfs(int[][] grid,int i,int j,int[] count,Queue<String> q) {
while(!q.isEmpty()) {
String s = q.remove();
//System.out.println(s); //prints correct indices
i = Integer.parseInt(s.substring(0,1));
j = Integer.parseInt(s.substring(1));
if(i - 1 > 0 && grid[i - 1][j] == 1) {
count[0]++;
i--;
grid[i][j] = 2;
q.add("" + i + j);
}
if(i + 1 < grid.length && grid[i + 1][j] == 1) {
count[0]++;
i++;
grid[i][j] = 2;
q.add("" + i + j);
}
if(j - 1 > 0 && grid[i][j - 1] == 1) {
count[0]++;
j--;
grid[i][j] = 2;
q.add("" + i + j);
}
if(j + 1 < grid.length && grid[i][j + 1] == 1) {
count[0]++;
j++;
grid[i][j] = 2;
q.add("" + i + j);
}
}
}
}
对于上面引用的示例,我的代码输出-1,因为它在最终循环中仍然找到1,而实际上并没有。
您能帮我弄清楚为什么会这样吗?
解决方法
几个问题:
-
从不检查第0列或第0行中的单元格是否感染了橙色。当
i - 1 > 0
为1时,比较i
是不正确的,但您还应该检查grid[0][j]
...j
也会出现相同的问题。 -
通过用
i
修改i--
,会影响下一个if
条件,这些条件旨在查看i
的原始值。因此,您不应更改i
的值(也不更改j
),而应在不修改grid[i-1][j]
的情况下将其分配给i
。 -
在
bfs
中,将j
索引与grid.length
进行了错误比较。应该将其与grid[i].length
进行比较,因为不能保证网格是正方形。 -
每个变烂的橙色的计数都会增加,但这不是应该计数的数量。许多桔子会在相同分钟内变烂,您应该只数分钟,而不是桔子。要正确计数,您应该进行两项更改:
-
只有在您收集了队列中所有烂橙后,才对
bfs
进行初始呼叫,因为它们都属于分钟0。 -
在
bfs
函数本身中,将新的烂橙子添加到单独的队列中,这样您就可以知道在这一特定分钟中添加了哪些橙子。然后,当原始队列变空时,将第二个队列移至第一个队列,等待一分钟,然后重复。
-
-
这没问题,但是不需要将
i
和j
作为参数传递给bfs
,并且让{{ 1}} 返回计数。
为了使它正常工作,我尝试不对代码进行过多更改:
bfs
肯定有一些方法可以使此过程更有效地运行,例如使用数组而不是队列。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。