【声明】
如果有侵权,请联系作者删除侵权部分。
如果有错误,请联系作者修改错误部分。
如果有转载,请标明出处。
【难度】简单
【题目】
给你一个大小为 rows x cols
的矩阵 mat
,其中 mat[i][j]
是 0
或 1
,请返回 矩阵 mat
中特殊位置的数目 。
特殊位置 定义:如果 mat[i][j] == 1 并且第 i 行和第 j 列中的所有其他元素均为 0(行和列的下标均 从 0 开始 ),则位置 (i, j) 被称为特殊位置。
【示例】
示例 1:
输入:mat = [[1,0,0],
[0,0,1],
[1,0,0]]
输出:1
解释:(1,2) 是一个特殊位置,因为 mat[1][2] == 1 且所处的行和列上所有其他元素都是 0
示例 2:
输入:mat = [[1,0,0],
[0,1,0],
[0,0,1]]
输出:3
解释:(0,0), (1,1) 和 (2,2) 都是特殊位置
示例 3:
输入:mat = [[0,0,0,1],
[1,0,0,0],
[0,1,1,0],
[0,0,0,0]]
输出:2
示例 4:
输入:mat = [[0,0,0,0,0],
[1,0,0,0,0],
[0,1,0,0,0],
[0,0,1,0,0],
[0,0,0,1,1]]
输出:3
【题目链接】https://leetcode-cn.com/problems/special-positions-in-a-binary-matrix/
【解题思路】
特殊位置的定义:如果mat[i][j]的值为1,且第i行和第j列的其他元素均为0。
根据特殊位置的定义,可以想到一种思路,就是遍历矩阵中所有的元素,见到值为1的元素,就遍历该元素所在行和列的其他元素,如果其他元素均为0,那么该位置符合特殊位置的定义。该方法有个缺点:时间复杂度较高,原因是每找到一个值为1的元素,便要遍历该元素所在的行和列。
因为需要找到值为1的元素,所以遍历矩阵的操作是不能进行优化的。找到值为1的元素后,需要判断该元素所在行和列的其他元素是否为0。这一步可以进行优化,如果某元素的值为1,该元素所在的行和列其他元素均为0,那么该元素所在行的和为1,所在列的和也为1。因此,可以先将矩阵中每行每列的值都先算出来,以供后面使用。
假设当前已经有了矩阵中每行每列和的值,当找到值为1的元素时,只需要去看该元素所在行和列的和是否为1即可。如果该元素所在行和列的和均为1,则该元素为特殊位置。
【代码】
class Solution {
public:
int numSpecial(vector<vector<int>>& mat) {
int rownum = mat.size();
int colnum = mat[0].size();
vector<int> rowsum(rownum, 0), colsum(colnum, 0);
for (int i = 0; i < rownum; ++ i) { //求出每行每列的和
for (int j = 0; j < colnum; ++ j) {
rowsum[i] += mat[i][j];
colsum[j] += mat[i][j];
}
}
int result = 0;
for (int i = 0; i < mat.size(); ++ i) {
for (int j = 0; j < mat[0].size(); ++ j) {
//元素值为1,且所在行和列的和均为1
if (mat[i][j] == 1 && rowsum[i] == 1 && colsum[j] == 1)
++ result;
}
}
return result;
}
};
【心得】
上面代码求每行每列和的部分是我参考别人代码写的,这种求矩阵每行每列和的方法可以只遍历一遍矩阵元素就完成所有的求和操作。比我之前的方法要好,我之前将行和列的求和操作分开了,相当于矩阵中每个元素我都遍历了两遍,不如这种方法好。