题目来源
题目描述
题目解析
暴力模拟:
c++
int oddCells(int n, int m, vector<vector<int>>& indices) {
vector<vector<int>> res(n, vector<int>(m));
for (auto cur : indices) {
for (int i = 0; i < m; i++)
res[cur[0]][i]++;
for (int i = 0; i < n; i++)
res[i][cur[1]]++;
}
int cnt = 0;
for(int i = 0;i<n;i++){
for(int j = 0;j<m;j++){
cnt += res[i][j]%2;
}
}
return cnt;
}
java
public static int oddCells(int n, int m, int[][] indices) {
int[][] arr = new int[n][m];
for (int i = 0; i < indices.length; i++){
int col = indices[i][0]; // 第i行第一个元素
int lin = indices[i][1];
for (int a = 0; a < m; a++){
arr[col][a]++;
}
for (int a = 0; a < n; a++){
arr[a][lin]++;
}
}
int num = 0;
for (int i = 0; i < arr.length; i++){
for (int j = 0 ; j < arr[i].length; j++){
if (arr[i][j]%2 != 0){
num++;
}
}
}
return num;
}
阴影面积法
一次遍历中记录奇数的行数(odd_rows)和列数(odd_cols)。
此时奇数行和奇数列不重叠的部分为奇数,重叠的部分则为偶数。
下面有多种数学思路,提2个:
1.循环出来以后用数学求解。
返回值 = odd_rows * m + odd_cols * n - 2 * odd_rows * odd_cols
解释:先把行上的所有奇数与列上的所有奇数相加(先不管重叠部分)。再减去重叠的部分(偶数),由于重叠部分在奇数行和奇数列中分别被当作奇数加了一次,所以减去时需要乘以2。
2.这样想也行(结果与上相同):
返回值 = odd_rols * (m - odd_cols) + odd_cols * (n - odd_rows)
解释:将奇数行不重叠的部分(奇数)与奇数列不重叠的部分(奇数)相加。
public static int oddCells(int n, int m, int[][] indices) {
boolean[] bal = new boolean[n];
boolean[] vert = new boolean[m];
int row = 0;
int line = 0;
for (int i = 0; i < indices.length; i++){
int a = indices[i][0];
int b = indices[i][1];
/*
* 初始: false, 为0
* 第一次加:变成奇数, !false=true, row++; 为1, bal[a] = true
* 第二次加:变成偶数, row--; 为2,
* */
if (!bal[a]){ //
row++;
bal[a] = true;
}else{
row--;
bal[a] = false;
}
if (!vert[b]){
line++;
vert[b] = true;
}else{
line--;
vert[b] = false;
}
}
// row * m
return row * m + line * n - 2 * row * line;
}