Special Positions in a Binary Matrix
EasyPrompt
Given an m x n binary matrix mat, return the number of special positions in mat.
A position (i, j) is called special if mat[i][j] == 1 and all other elements in row i and column j are 0 (rows and columns are 0-indexed).
Example 1:
Input: mat = [[1,0,0],[0,0,1],[1,0,0]]
Output: 1
Explanation: (1, 2) is a special position because mat[1][2] == 1 and all other elements in row 1 and column 2 are 0.Example 2:
Input: mat = [[1,0,0],[0,1,0],[0,0,1]]
Output: 3
Explanation: (0, 0), (1, 1) and (2, 2) are special positions.
Constraints:
m == mat.lengthn == mat[i].length1 <= m, n <= 100mat[i][j]is either0or1.
Approaches
2 approaches with complexity analysis and trade-offs.
This approach involves iterating through every single cell of the matrix. For each cell that contains a 1, we then perform a check to see if it qualifies as a "special" position. This check involves scanning the entire corresponding row and column to ensure all other elements are 0.
Algorithm
- Initialize
specialCount = 0. - Get matrix dimensions
m(rows) andn(columns). - For
ifrom0tom-1:- For
jfrom0ton-1:- If
mat[i][j] == 1:- Set a flag
isSpecial = true. - Check the row: For
kfrom0ton-1:- If
k != jandmat[i][k] == 1, setisSpecial = falseand break the loop.
- If
- If
isSpecialisfalse, continue to the nextj. - Check the column: For
kfrom0tom-1:- If
k != iandmat[k][j] == 1, setisSpecial = falseand break the loop.
- If
- If
isSpecialis stilltrue, incrementspecialCount.
- Set a flag
- If
- For
- Return
specialCount.
Walkthrough
The algorithm proceeds as follows:
- Initialize a counter
specialCountto 0. - Iterate through each cell
(i, j)of the matrixmat, whereiis the row index andjis the column index. - If
mat[i][j]is1, we need to verify if it's a special position. - To do this, we check two conditions:
a. Row Check: Iterate through all elements in row
i. If we find another1(at a columnkwherek != j), then this position is not special. b. Column Check: Iterate through all elements in columnj. If we find another1(at a rowkwherek != i), then this position is not special. - If both the row and column checks pass (meaning no other
1s were found), it means(i, j)is a special position. IncrementspecialCount. - After checking all cells, the value of
specialCountis the result.
class Solution { public int numSpecial(int[][] mat) { int m = mat.length; int n = mat[0].length; int specialCount = 0; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { boolean isSpecial = true; // Check row i for (int k = 0; k < n; k++) { if (k != j && mat[i][k] == 1) { isSpecial = false; break; } } if (!isSpecial) continue; // Check column j for (int k = 0; k < m; k++) { if (k != i && mat[k][j] == 1) { isSpecial = false; break; } } if (isSpecial) { specialCount++; } } } } return specialCount; }}Complexity
Time
O(m * n * (m + n)). For each of the `m * n` cells, if it's a `1`, we scan its row (size `n`) and its column (size `m`). In the worst case, this leads to the specified complexity.
Space
O(1). We only use a few variables to keep track of the count and loop indices, which is constant extra space.
Trade-offs
Pros
Simple to understand and implement.
Requires no extra space beyond the input matrix.
Cons
Highly inefficient due to redundant computations. The same row or column is scanned multiple times for different
1s within them.
This approach optimizes the brute-force method by avoiding redundant calculations. Instead of repeatedly scanning rows and columns, we first pre-calculate the sum of 1s for every row and every column. A position (i, j) is special if and only if mat[i][j] == 1, the sum of its row is 1, and the sum of its column is 1.
Algorithm
- Get matrix dimensions
m(rows) andn(columns). - Initialize
rowSumarray of sizemwith all zeros. - Initialize
colSumarray of sizenwith all zeros. - Pre-computation Pass:
- For
ifrom0tom-1:- For
jfrom0ton-1:- If
mat[i][j] == 1:- Increment
rowSum[i]. - Increment
colSum[j].
- Increment
- If
- For
- For
- Initialize
specialCount = 0. - Counting Pass:
- For
ifrom0tom-1:- For
jfrom0ton-1:- If
mat[i][j] == 1androwSum[i] == 1andcolSum[j] == 1:- Increment
specialCount.
- Increment
- If
- For
- For
- Return
specialCount.
Walkthrough
The algorithm is divided into two main phases:
-
Pre-computation Phase:
- Create two arrays:
rowSumof sizem(number of rows) andcolSumof sizen(number of columns), both initialized to zeros. - Iterate through the entire matrix
matonce. For each elementmat[i][j], if it's a1, incrementrowSum[i]andcolSum[j]. After this pass,rowSum[i]will hold the total number of1s in rowi, andcolSum[j]will hold the total number of1s in columnj.
- Create two arrays:
-
Counting Phase:
- Initialize a counter
specialCountto 0. - Iterate through the matrix
mata second time. - For each cell
(i, j), check if it meets all three conditions for being a special position: a.mat[i][j] == 1b.rowSum[i] == 1c.colSum[j] == 1 - If all three conditions are true, increment
specialCount. - After iterating through all cells, return
specialCount.
- Initialize a counter
class Solution { public int numSpecial(int[][] mat) { int m = mat.length; int n = mat[0].length; int[] rowSum = new int[m]; int[] colSum = new int[n]; // Pre-compute row and column sums for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1) { rowSum[i]++; colSum[j]++; } } } int specialCount = 0; // Count special positions for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (mat[i][j] == 1 && rowSum[i] == 1 && colSum[j] == 1) { specialCount++; } } } return specialCount; }}Complexity
Time
O(m * n). We traverse the matrix twice. The first traversal is for pre-computation, and the second is for counting. Both take `O(m * n)` time, which is a significant improvement.
Space
O(m + n). We use two additional arrays, `rowSum` and `colSum`, to store the sums, requiring space proportional to the number of rows plus the number of columns.
Trade-offs
Pros
Much more efficient than the brute-force approach in terms of time.
The logic is clear and directly follows the definition of a special position.
Cons
Requires extra space for the sum arrays, proportional to the dimensions of the matrix.
Solutions
Solution
class Solution {public int numSpecial(int[][] mat) { int m = mat.length, n = mat[0].length; int[] r = new int[m]; int[] c = new int[n]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { r[i] += mat[i][j]; c[j] += mat[i][j]; } } int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (mat[i][j] == 1 && r[i] == 1 && c[j] == 1) { ++ans; } } } return ans; }}class Solution {public: int numSpecial(vector<vector<int>> &mat) { int m = mat.size(), n = mat[0].size(); vector<int> r(m), c(n); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { r[i] += mat[i][j]; c[j] += mat[i][j]; } } int ans = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (mat[i][j] == 1 && r[i] == 1 && c[j] == 1) { ++ans; } } } return ans; }};class Solution: def numSpecial(self, mat: List[List[int]]) -> int: m, n = len(mat), len(mat[0]) r = [0] * m c = [0] * n for i, row in enumerate(mat): for j, v in enumerate(row): r[i] += v c[j] += v ans = 0 for i in range(m): for j in range(n): if mat[i][j] == 1 and r[i] == 1 and c[j] == 1: ans += 1 return ansVideo walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.