CodeSignal房间求和问题:多维数组转单个数组及代码调试
问题:CodeSignal房间费用累加计算
题目描述:
每个房间有不同的费用,部分房间免费,但传闻所有免费房间闹鬼!由于CodeBots十分迷信,它们拒绝入住任何免费房间,或免费房间正下方的任何房间。
给定整数矩形矩阵matrix,其中每个值代表房间费用,你的任务是返回所有适合CodeBots入住的房间总费用(即累加所有不是0,且不在0的正下方的数值)。
示例
输入矩阵:
matrix = [[0, 1, 1, 2], [0, 5, 0, 0], [2, 0, 3, 3]]
输出应为 solution(matrix) = 9。
我的错误代码
function solution(matrix) { let rooms = [] for (let i = 0; i < matrix.length; i++) { if (matrix[i] !== 0 || matrix[i-4] !== 0) { rooms.push(i) } } rooms.reduce((a, b) => a + b, 0) }
疑问
我认为代码不通过的原因是矩阵由多个子数组组成,请问是否有简便方法将这些子数组合并为一个大数组,再遍历执行条件判断?
解答
先说说你代码里的核心问题
- 遍历逻辑错了:你只遍历了矩阵的外层数组(每一行),没遍历每行里的单个房间,
matrix[i]拿的是一整行,不是单个房间值。 - 判断逻辑错了:题目要排除0本身和0正下方的房间,你用的
||逻辑不对,而且matrix[i-4]这种写法完全没意义,正下方指的是上一行同一列的位置。 - 没返回结果:
reduce计算完后没有return出去。
关于合并数组的方法
把二维数组合并成一维可以用matrix.flat(),比如:
const flatMatrix = matrix.flat();
但合并后你得记录每个元素原来的行列位置才能判断正上方是不是0,反而更麻烦,不如直接遍历二维数组高效。
正确的实现思路
- 初始化总费用为0。
- 遍历每一行,再遍历该行每个元素:
- 当前元素是0,直接跳过。
- 当前元素不是0,检查上一行同一列是不是0,是0就跳过。
- 符合条件的元素累加到总费用。
- 返回总费用。
示例代码
function solution(matrix) { let total = 0; // 遍历每一行 for (let row = 0; row < matrix.length; row++) { // 遍历当前行的每个房间 for (let col = 0; col < matrix[row].length; col++) { const current = matrix[row][col]; // 跳过免费房间 if (current === 0) continue; // 第一行没有上一行,直接累加 if (row === 0) { total += current; } else { // 检查上一行同一列是不是0,不是的话累加 if (matrix[row-1][col] !== 0) { total += current; } } } } return total; }
测试示例输入:
- 第一行:0跳过,1、1、2累加,总和4。
- 第二行:0跳过,5的上方是1(非0),累加5;后两个0跳过,总和9。
- 第三行:2的上方是0(第二行第一列是0),跳过;0跳过;3的上方是0,跳过;3的上方是0,跳过。最终总和9,符合要求。
更简洁的写法(用数组方法)
function solution(matrix) { return matrix.reduce((total, row, rowIdx) => { return total + row.reduce((rowSum, val, colIdx) => { if (val === 0) return rowSum; if (rowIdx === 0 || matrix[rowIdx-1][colIdx] !== 0) { return rowSum + val; } return rowSum; }, 0); }, 0); }
内容的提问来源于stack exchange,提问作者Brittany Hilliard
相关产品推荐
相关产品推荐

