You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二维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. 边界处理:先判断数组为空或长宽均≤1的情况,直接返回0
  2. 去重机制:使用visited布尔数组记录已统计的0,确保每个0只被计数一次
  3. 方向数组:用二维数组统一管理四个相邻方向,代码更简洁易维护
  4. 越界检查:访问相邻元素前先判断索引合法性,避免数组越界异常
  5. 全遍历:遍历数组中所有元素,不会遗漏边缘的1及其相邻0

测试验证

运行以下驱动代码:

System.out.println(borderZeros(nums1)); // 输出10
System.out.println(borderZeros(nums2)); // 输出18

内容的提问来源于stack exchange,提问作者Iyo31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:15:24