一、1582. 二进制矩阵中的特殊位置【简】
一般太简单的题目我就不记录每日一题了,但这道题的一个解法有点意思。
1、题目:
给你一个大小为 rows x cols 的矩阵 mat,其中 mat[i][j] 是 0 或 1,请返回 矩阵 mat 中特殊位置的数目 。
特殊位置 定义:如果 mat[i][j] == 1 并且第 i 行和第 j 列中的所有其他元素均为 0(行和列的下标均 从 0 开始 ),则位置 (i, j) 被称为特殊位置。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/special-positions-in-a-binary-matrix
2、思路一:常规思路
必定是需要遍历整个矩阵才能知道某个位置是否是1,时间复杂度至少是O(rows x cols)。
- 设置两个数组row[rows]、cow[cows],第一次遍历整个数组,分别记录行/列中1的个数。空间复杂度O(rows+cols);
- 第二次遍历数组,当mat[i][j]==1时,若row[i] ==1 且 cow[j]==1,说明是特殊位置,记录。
代码:
class Solution {
public:
int numSpecial(vector<vector<int>>& mat) {
vector<int> row(mat.size());
vector<int> col(mat[0].size());
int res = 0;
// 第一次遍历
for(int i =0;i<mat.size();i++){
for(int j =0;j<mat[0].size();j++){
if(mat[i][j] == 1){
row[i] ++;
col[j] ++;
}
}
}
// 第二次遍历
for(int i =0;i<mat.size();i++){
for(int j =0;j<mat[0].size();j++){
if(mat[i][j] == 1&& row[i]==1&&col[j]==1){
res++;
}
}
}
return res;
}
};
3、思路二
第二种解法来自官方解,可以使空间复杂度为O(1),自己想的时候没想出来怎么可能空间复杂度这么低,看答案的时候发现,其实思路一样,但记录是在原矩阵上进行记录。
观察到若某个位置是特殊位置时,其行和列都是只会有1个1。所以可以用原矩阵第一行,去记录某一列中的所有的1,对应的那一行的1的个数,之和,当且仅当这个值为1的时候,这一列才会有一个特殊位置,且特殊位置一列只有一个。
- 循环所有行,循环行内所有元素求得一行1的个数row1,然后再一次循环行内所有元素,当mat[i][j]==1时,将row1加到第一行mat[0][j]。注意:当第二次循环所有元素的时候,因为第一行可能本来有1,而第一行是为了降低空间复杂度去记录值的,默认应该是0,所以当mat[i][j]==1时让mat[0][j] = row1。
- 最后循环一次第一行,1的个数即为特殊位置数量。
例子:
例如第二列,mat[1][1]和mat[2][1]都是1,mat[1][1]那一行有2个1,mat[2][1]那一行有2个1,所以mat[0][1] = 4。
因此第一行[1, 4, 2, 3],该例子只有一个特殊位置。
代码:
class Solution {
public:
int numSpecial(vector<vector<int>>& mat) {
int res = 0;
// 循环所有行
for(int i = 0;i<mat.size();i++){
int row1 = 0;
// 第一次循环i行所有元素,记录行内1数量
for(int j =0;j<mat[0].size();j++){
if(mat[i][j]==1){
row1 ++;
}
}
// 第二次循环i行所有元素
for(int j =0;j<mat[0].size();j++){
if(mat[i][j]==1){
if(i == 0){
mat[0][j] = row1;
}else{
mat[0][j] += row1;
}
}
}
}
for(int j =0;j<mat[0].size();j++){
if(mat[0][j] == 1){
res++;
}
}
return res;
}
};