求助:我的Flood Fill算法为何出现StackOverflowError?
为什么你的Flood Fill递归实现会引发StackOverflowError?
核心原因
- 递归深度超过JVM栈容量:你的网格尺寸是102×102(x、y范围0到101),如果需要遍历的连通区域很大(比如大部分单元格都不是1),递归调用链的长度会随着遍历的单元格数量线性增长。Java默认线程栈的深度通常只有几千级(具体数值取决于JVM配置),当递归次数超过这个阈值时,栈帧堆积过多就会触发StackOverflowError。
- 虽然你用
went数组标记了已访问的坐标,避免了重复访问,但递归调用的栈帧不会因为标记而减少,只要遍历的单元格足够多,栈溢出就必然会发生。
解决方法
1. 改用迭代实现(推荐)
用栈(DFS)或队列(BFS)手动管理遍历过程,彻底避开递归栈的限制。以下是迭代版DFS的示例:
public static int flood(int startX, int startY) { int result = 0; Stack<int[]> stack = new Stack<>(); stack.push(new int[]{startX, startY}); while (!stack.isEmpty()) { int[] pos = stack.pop(); int x = pos[0]; int y = pos[1]; // 边界和已访问判断 if (x < 0 || y < 0 || x > 101 || y > 101 || went[x][y]) { continue; } went[x][y] = true; // 遇到目标单元格计数 if (grid[x][y] == 1) { result++; continue; } // 按相反顺序压栈,保证和递归遍历顺序一致(可选) stack.push(new int[]{x, y-1}); stack.push(new int[]{x-1, y}); stack.push(new int[]{x, y+1}); stack.push(new int[]{x+1, y}); } return result; }
2. 调整JVM栈大小(不推荐)
启动Java程序时通过-Xss参数增大栈容量,比如java -Xss2m YourMainClass。但这种方法只是临时缓解,一旦网格尺寸继续增大,还是会出现栈溢出,而且会占用更多内存资源,不适合通用场景。
内容的提问来源于stack exchange,提问作者Milka1968
相关产品推荐
相关产品推荐

