JavaScript统计二维数组行/列中遇0前的连续1出现次数
问题解答
现有代码问题排查
你的代码无法得到正确结果是因为两个核心错误:
- 条件判断逻辑错误:
if ( j === 1 )是判断当前遍历的下标是否为1,而非判断当前数组元素是否为1,正确写法应该是if (row[j] === 1) - 边界逻辑缺失:
- 遍历到0时直接push计数会把大量0值(比如行开头连续0的计数)塞进结果,需要判断计数>0时才推入结果
- 遍历结束后如果行末尾是连续1,这段计数没有被推入结果数组
- 结果格式没有适配:你要的grid[0]返回单个数字9,需要额外判断结果数组长度是否为1,是就返回元素本身,否则返回数组。
一次性遍历同时统计行、列连续1的方案
不需要分别遍历行和列,一次全量遍历所有元素即可同时完成行、列的统计,时间复杂度为O(mn)(m为行数,n为列数),这是理论最优复杂度,因为每个元素至少需要读取一次,不存在更低复杂度的实现。
实现思路:
- 提前初始化行计数缓存、行结果数组,列计数缓存、列结果数组
- 遍历每个元素
grid[i][j]时,同时更新第i行、第j列的连续1计数 - 遇到0时,如果对应行/列的计数大于0,就把计数推入对应结果数组,重置计数为0
- 遍历结束后,把所有行、列剩余的未推入的计数(末尾连续1的情况)补充到结果数组
完整实现代码
var grid = [ [0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0], [0,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,1,0,0,0,0,0] ]; const rowNum = grid.length; const colNum = grid[0].length; // 初始化行统计变量 const rowResult = new Array(rowNum).fill(0).map(() => []); const rowCount = new Array(rowNum).fill(0); // 初始化列统计变量 const colResult = new Array(colNum).fill(0).map(() => []); const colCount = new Array(colNum).fill(0); // 一次遍历完成所有统计 for (let i = 0; i < rowNum; i++) { for (let j = 0; j < colNum; j++) { const val = grid[i][j]; // 处理行统计 if (val === 1) { rowCount[i]++; } else { if (rowCount[i] > 0) { rowResult[i].push(rowCount[i]); rowCount[i] = 0; } } // 处理列统计 if (val === 1) { colCount[j]++; } else { if (colCount[j] > 0) { colResult[j].push(colCount[j]); colCount[j] = 0; } } } // 每行遍历结束,补入行末尾的连续1计数 if (rowCount[i] > 0) { rowResult[i].push(rowCount[i]); rowCount[i] = 0; } } // 所有行遍历结束,补入每列末尾的连续1计数 for (let j = 0; j < colNum; j++) { if (colCount[j] > 0) { colResult[j].push(colCount[j]); } } // 适配你要的输出格式:长度为1的数组返回单个数字 const formatResult = (arr) => arr.length === 1 ? arr[0] : arr; // 测试行结果 console.log(formatResult(rowResult[0])); // 输出9 console.log(formatResult(rowResult[1])); // 输出[3,3] console.log(formatResult(rowResult[2])); // 输出[2,1,1,2]
更优的数据组织建议
- 如果grid数据是固定不变的:预处理一次把行、列的统计结果缓存下来,后续所有使用场景直接读取缓存即可,不需要重复计算
- 如果grid会频繁修改单个元素:不需要全量重算,只需要重新计算修改位置对应的那一行、那一列的统计结果即可,时间复杂度可以降到O(m + n)每次修改
- 如果需要高频查询某一行/列的连续1统计结果:可以提前把格式化后的结果存在单独的对象/数组里,直接索引读取即可
内容的提问来源于stack exchange,提问作者DK James
相关产品推荐
相关产品推荐

