二维0-1数组边界0计数算法实现求助
问题:统计与1相邻的去重0的数量
现有一个随机长宽的二维数组zeroesAndOnes,元素为随机0或1。需要实现算法统计与1存在上下左右边界相邻(不含对角线)的0的数量,同一个0被多个1相邻时仅计数一次。
要求
- 若数组长宽均≤1,直接返回0
- 不能出现数组越界异常
- 测试数组
nums1、nums2调用borderZeros方法预期输出分别为10和18
测试数组
int[][] nums1 = { {0, 0, 1, 0, 1, 0, 1, 0}, {1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0}, }; int[][] nums2 = { {0, 0, 0, 0, 1, 1}, {0, 1, 0, 0, 1, 0}, {0, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 0}, {0, 0, 0, 0, 1, 1}, };
方法定义框架
public static int borderZeros(int[][] nums) { int border = 0; // 实现逻辑 return border; }
当前尝试的代码及问题
public static int borderZeros(int[][] nums) { int border = 0; for (int r = 1; r < nums.length - 1; r++) { for (int c = 1; c < nums[r].length - 1; c++) { if (nums[r][c] == 1) { if (nums[r - 1][c] == 0) { border++; } if (nums[r][c - 1] == 0) { border++; } if (nums[r + 1][c] == 0) { border++; } if (nums[r][c + 1] == 0) { border++; } } else { continue; } } } return border; }
上述代码存在以下问题:
- 数组越界:直接访问
r-1、r+1、c-1、c+1时,未判断是否超出数组索引范围 - 未去重:同一个0被多个1相邻时会被重复计数
- 元素遗漏:仅遍历数组中间元素,边缘的1未被处理,导致对应相邻0未统计
优雅高效的Java解决方案
public static int borderZeros(int[][] nums) { // 边界情况:数组为空,或行数≤1且列数≤1 if (nums == null || nums.length == 0 || (nums.length <= 1 && nums[0].length <= 1)) { return 0; } int rows = nums.length; int cols = nums[0].length; // 用于标记已统计过的0,避免重复计数 boolean[][] visited = new boolean[rows][cols]; int count = 0; // 四个方向:上、下、左、右 int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; for (int r = 0; r < rows; r++) { for (int c = 0; c < cols; c++) { // 找到所有1的位置,检查其相邻元素 if (nums[r][c] == 1) { for (int[] dir : directions) { int newR = r + dir[0]; int newC = c + dir[1]; // 检查相邻位置是否在数组范围内,且是未被统计的0 if (newR >= 0 && newR < rows && newC >= 0 && newC < cols && nums[newR][newC] == 0 && !visited[newR][newC]) { visited[newR][newC] = true; count++; } } } } } return count; }
方案关键点说明
- 边界处理:先判断数组为空或长宽均≤1的情况,直接返回0
- 去重机制:使用
visited布尔数组记录已统计的0,确保每个0只被计数一次 - 方向数组:用二维数组统一管理四个相邻方向,代码更简洁易维护
- 越界检查:访问相邻元素前先判断索引合法性,避免数组越界异常
- 全遍历:遍历数组中所有元素,不会遗漏边缘的1及其相邻0
测试验证
运行以下驱动代码:
System.out.println(borderZeros(nums1)); // 输出10 System.out.println(borderZeros(nums2)); // 输出18
内容的提问来源于stack exchange,提问作者Iyo31
相关产品推荐
相关产品推荐

