Easy
题目描述
给你一个 m x n 的二进制矩阵 mat,请你返回矩阵 mat 中特殊位置的数目。
如果位置 (i, j) 满足 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 且所在的第1行和第2列的其他元素都是 0
示例 2:
输入:mat = [[1,0,0],[0,1,0],[0,0,1]]
输出:3
解释:(0,0), (1,1) 和 (2,2) 都是特殊位置
提示:
m == mat.lengthn == mat[i].length1 <= m, n <= 100mat[i][j]是0或1
解题思路
解题思路
这道题的关键在于理解特殊位置的定义:位置 (i,j) 是特殊位置当且仅当该位置值为1,且该位置所在的行和列都只有这一个1。
方法一:预处理统计(推荐) 首先统计每行和每列中1的个数,然后遍历矩阵。对于每个值为1的位置,检查其所在行和列是否都只有一个1。
算法流程:
- 遍历矩阵,统计每行中1的个数存储在
rowCount数组中 - 统计每列中1的个数存储在
colCount数组中 - 再次遍历矩阵,对于每个
mat[i][j] == 1的位置:- 如果
rowCount[i] == 1且colCount[j] == 1,则该位置是特殊位置
- 如果
- 返回特殊位置的总数
方法二:直接验证 对于每个值为1的位置,直接检查其所在行和列是否只有这一个1。时间复杂度较高但逻辑简单。
预处理方法的优势在于避免了重复计算,时间复杂度更优,是推荐解法。
代码实现
class Solution {
public:
int numSpecial(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
vector<int> rowCount(m, 0), colCount(n, 0);
// 统计每行每列的1的个数
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) {
rowCount[i]++;
colCount[j]++;
}
}
}
int result = 0;
// 检查特殊位置
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1 && rowCount[i] == 1 && colCount[j] == 1) {
result++;
}
}
}
return result;
}
};
class Solution:
def numSpecial(self, mat: List[List[int]]) -> int:
m, n = len(mat), len(mat[0])
row_count = [0] * m
col_count = [0] * n
# 统计每行每列的1的个数
for i in range(m):
for j in range(n):
if mat[i][j] == 1:
row_count[i] += 1
col_count[j] += 1
result = 0
# 检查特殊位置
for i in range(m):
for j in range(n):
if mat[i][j] == 1 and row_count[i] == 1 and col_count[j] == 1:
result += 1
return result
public class Solution {
public int NumSpecial(int[][] mat) {
int m = mat.Length, n = mat[0].Length;
int[] rowCount = new int[m];
int[] colCount = new int[n];
// 统计每行每列的1的个数
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1) {
rowCount[i]++;
colCount[j]++;
}
}
}
int result = 0;
// 检查特殊位置
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (mat[i][j] == 1 && rowCount[i] == 1 && colCount[j] == 1) {
result++;
}
}
}
return result;
}
}
var numSpecial = function(mat) {
const m = mat.length;
const n = mat[0].length;
let count = 0;
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (mat[i][j] === 1) {
let rowSum = mat[i].reduce((sum, val) => sum + val, 0);
let colSum = 0;
for (let k = 0; k < m; k++) {
colSum += mat[k][j];
}
if (rowSum === 1 && colSum === 1) {
count++;
}
}
}
}
return count;
};
复杂度分析
| 复杂度类型 | 预处理方法 | 直接验证方法 |
|---|---|---|
| 时间复杂度 | O(m×n) | O(m×n×(m+n)) |
| 空间复杂度 | O(m+n) | O(1) |