今日打卡题目:1252. 奇数值单元格的数目
题目描述
给你一个 m x n 的矩阵,最开始的时候,每个单元格中的值都是 0。
另有一个二维索引数组 indices,indices[i] = [ri, ci] 指向矩阵中的某个位置,其中 ri 和 ci 分别表示指定的行和列(从 0 开始编号)。
对 indices[i] 所指向的每个位置,应同时执行下述增量操作:
ri 行上的所有单元格,加 1 。 ci 列上的所有单元格,加 1 。
给你 m、n 和 indices 。请你在执行完所有 indices 指定的增量操作后,返回矩阵中 奇数值单元格 的数目。
解答思路
- 矩阵一般用二维数组存储,可以用 new Array() 生成数组,并用 fill() 方法进行填充;
- 对 indices 进行遍历,按顺序对二维数组进行操作;
- 统计奇数个数。
答题时出现的问题
- 修改列值时,修改了一个,其余行的值均发生了改变。
问题代码
var oddCells = function(m, n, indices) {
let arr = new Array(m).fill(new Array(n).fill(0))
for(let i = 0; i < indices.length; i++) {
arr[indices[i][0]] = arr[indices[i][0]].map(item => {
return ++item
})
arr.map((item,index) => {
item[indices[i][1]] = ++item[indices[i][1]] //
})
}
let count = 0
arr.map(item1 => {
item1.map(item2 => {
if(item2%2 !== 0) count++
})
})
return count
};
做完行处理后:
进行列处理时:
此时 index 为 1,但是 index 为2,3,4的值均发生了改变。
问题原因: 如果value值为一个引用数据类型,则fill之后,数组里面的值指向的是同一个地址。如果改变了其中一个,则其它的都会改变。
解决办法:
- 深复制;
- 用双重 for 循环创建二维数组。
通过代码:
* @param {number} m
* @param {number} n
* @param {number[][]} indices
* @return {number}
*/
var oddCells = function(m, n, indices) {
let arr = new Array(m).fill(new Array(n).fill(0))
for(let i = 0; i < indices.length; i++) {
arr[indices[i][0]] = arr[indices[i][0]].map(item => {
return ++item
})
arr.map((item,index) => {
let a = JSON.parse(JSON.stringify(item))
a[indices[i][1]] = a[indices[i][1]] + 1
arr[index] = JSON.parse(JSON.stringify(a))
})
}
let count = 0
arr.map(item1 => {
item1.map(item2 => {
if(item2%2 !== 0) {++count; }
})
})
return count
};
官方思路学习点:
- 用 map 来生成二维数组,其余同上。
let arr = new Array(m).fill(0).map(() => new Array(n).fill(0))
- 用 &1 来判断奇偶,奇数返回1,偶数返回0.
3 & 1 // 1
2 & 1 // 0
- 用模拟空间解决
由于每次操作只会将一行和一列的数增加 1,因此我们可以使用一个行数组 rows 和列数组 cols 分别记录每一行和每一列被增加的次数。对于indices 中的每一对 [ri, ci],我们将 rows[ri] 和 cols[ci] 的值分别增加 1。 在所有操作完成后,我们可以计算出位置 (x,y) 位置的计数即为 rows[x]+cols[y]。遍历矩阵,即可得到所有奇数的数目。
var oddCells = function(m, n, indices) {
const rows = new Array(m).fill(0);
const cols = new Array(n).fill(0);
for (const index of indices) {
rows[index[0]]++;
cols[index[1]]++;
}
let res = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (((rows[i] + cols[j]) & 1) !== 0) {
res++;
}
}
}
return res;
};