1582. Special Positions in a Binary Matrix
Problem Description
You are given an m x n
binary matrix mat
(containing only 0s and 1s). Your task is to find the number of special positions in this matrix.
A position (i, j)
is considered special if it meets the following conditions:
- The value at position
(i, j)
is 1 (i.e.,mat[i][j] == 1
) - All other elements in row
i
are 0 - All other elements in column
j
are 0
In other words, a special position contains a 1 that is the only 1 in both its entire row and entire column.
The solution approach uses counting to efficiently solve this problem. It first counts how many 1s appear in each row and column using two arrays: rows
and cols
. The rows[i]
stores the count of 1s in row i
, and cols[j]
stores the count of 1s in column j
.
After counting, the algorithm traverses the matrix again. For each position that contains a 1, it checks if both rows[i] == 1
and cols[j] == 1
. This condition ensures that the current 1 is the only 1 in its row and column, making it a special position. The answer counter is incremented for each special position found.
This two-pass approach has a time complexity of O(m × n)
where m
and n
are the dimensions of the matrix.
Intuition
The key insight is that checking if a position is "special" requires verifying that it's the only 1
in its entire row and column. A naive approach would be to check every 1
we find by scanning its entire row and column, but this would be inefficient.
Instead, we can think about this problem differently: what if we knew in advance how many 1
s exist in each row and column? If we had this information, determining if a position is special becomes trivial - we just need to check if the position contains a 1
AND its row has exactly one 1
AND its column has exactly one 1
.
This leads us to a preprocessing step: we can make a single pass through the matrix to count the number of 1
s in each row and column. We store these counts in two arrays - rows[i]
tells us how many 1
s are in row i
, and cols[j]
tells us how many 1
s are in column j
.
With this preprocessing done, we make a second pass through the matrix. For each cell that contains a 1
, we check if rows[i] == 1
and cols[j] == 1
. If both conditions are true, this 1
must be the only 1
in its row and column, making it special.
This counting strategy transforms what could be an O(m × n × (m + n))
problem (checking every 1
by scanning its row and column) into an O(m × n)
problem (two passes through the matrix), making it much more efficient.
Solution Approach
The implementation follows a two-pass strategy using auxiliary arrays for counting:
Step 1: Initialize Counting Arrays
We create two arrays to track the count of 1
s:
rows = [0] * len(mat)
- stores the count of1
s in each rowcols = [0] * len(mat[0])
- stores the count of1
s in each column
Step 2: First Pass - Count 1
s in Each Row and Column
We iterate through the entire matrix using nested loops:
for i, row in enumerate(mat):
for j, x in enumerate(row):
rows[i] += x
cols[j] += x
Since the matrix is binary (contains only 0
s and 1
s), we can directly add the cell value x
to our counters. When x = 1
, it increments the respective row and column counters; when x = 0
, it adds nothing.
Step 3: Second Pass - Count Special Positions We traverse the matrix again to identify special positions:
ans = 0
for i, row in enumerate(mat):
for j, x in enumerate(row):
ans += x == 1 and rows[i] == 1 and cols[j] == 1
For each cell, we check three conditions:
x == 1
: The current cell contains a1
rows[i] == 1
: Rowi
has exactly one1
cols[j] == 1
: Columnj
has exactly one1
The expression x == 1 and rows[i] == 1 and cols[j] == 1
evaluates to True
(which equals 1
in Python) when all conditions are met, and False
(which equals 0
) otherwise. By adding this boolean result to ans
, we increment the counter only for special positions.
Time Complexity: O(m × n)
where m
and n
are the dimensions of the matrix (two passes through the matrix)
Space Complexity: O(m + n)
for the auxiliary arrays storing row and column counts
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with a small example matrix:
mat = [[1, 0, 0], [0, 0, 1], [1, 0, 0]]
Step 1: Initialize Counting Arrays
rows = [0, 0, 0]
(one counter for each of the 3 rows)cols = [0, 0, 0]
(one counter for each of the 3 columns)
Step 2: First Pass - Count 1s
We traverse each cell and update our counters:
- Position (0,0): value = 1 →
rows[0] += 1
,cols[0] += 1
→rows = [1, 0, 0]
,cols = [1, 0, 0]
- Position (0,1): value = 0 → no change
- Position (0,2): value = 0 → no change
- Position (1,0): value = 0 → no change
- Position (1,1): value = 0 → no change
- Position (1,2): value = 1 →
rows[1] += 1
,cols[2] += 1
→rows = [1, 1, 0]
,cols = [1, 0, 1]
- Position (2,0): value = 1 →
rows[2] += 1
,cols[0] += 1
→rows = [1, 1, 1]
,cols = [2, 0, 1]
- Position (2,1): value = 0 → no change
- Position (2,2): value = 0 → no change
After the first pass:
rows = [1, 1, 1]
(row 0 has one 1, row 1 has one 1, row 2 has one 1)cols = [2, 0, 1]
(column 0 has two 1s, column 1 has zero 1s, column 2 has one 1)
Step 3: Second Pass - Find Special Positions
Now we check each cell that contains a 1:
- Position (0,0): value = 1,
rows[0] = 1
,cols[0] = 2
→ NOT special (column 0 has 2 ones) - Position (1,2): value = 1,
rows[1] = 1
,cols[2] = 1
→ SPECIAL! (only 1 in its row and column) - Position (2,0): value = 1,
rows[2] = 1
,cols[0] = 2
→ NOT special (column 0 has 2 ones)
Result: 1 special position found at (1,2)
The position (1,2) is special because it's the only 1 in row 1 [0, 0, 1]
and the only 1 in column 2 [0, 1, 0]
.
Solution Implementation
1class Solution:
2 def numSpecial(self, mat: List[List[int]]) -> int:
3 # Get dimensions of the matrix
4 num_rows = len(mat)
5 num_cols = len(mat[0])
6
7 # Initialize arrays to store sum of each row and column
8 row_sums = [0] * num_rows
9 col_sums = [0] * num_cols
10
11 # Calculate the sum of 1s in each row and column
12 for i in range(num_rows):
13 for j in range(num_cols):
14 value = mat[i][j]
15 row_sums[i] += value
16 col_sums[j] += value
17
18 # Count special positions
19 special_count = 0
20
21 # Check each position in the matrix
22 for i in range(num_rows):
23 for j in range(num_cols):
24 # A position is special if:
25 # 1. The value at position (i,j) is 1
26 # 2. The sum of row i equals 1 (only one 1 in the row)
27 # 3. The sum of column j equals 1 (only one 1 in the column)
28 if mat[i][j] == 1 and row_sums[i] == 1 and col_sums[j] == 1:
29 special_count += 1
30
31 return special_count
32
1class Solution {
2 /**
3 * Counts the number of special positions in a binary matrix.
4 * A position (i, j) is special if mat[i][j] == 1 and all other elements
5 * in row i and column j are 0.
6 *
7 * @param mat The input binary matrix
8 * @return The count of special positions
9 */
10 public int numSpecial(int[][] mat) {
11 // Get matrix dimensions
12 int rowCount = mat.length;
13 int colCount = mat[0].length;
14
15 // Arrays to store the sum of 1s in each row and column
16 int[] rowSums = new int[rowCount];
17 int[] colSums = new int[colCount];
18
19 // First pass: Calculate the sum of elements in each row and column
20 for (int row = 0; row < rowCount; row++) {
21 for (int col = 0; col < colCount; col++) {
22 rowSums[row] += mat[row][col];
23 colSums[col] += mat[row][col];
24 }
25 }
26
27 // Second pass: Count special positions
28 int specialCount = 0;
29 for (int row = 0; row < rowCount; row++) {
30 for (int col = 0; col < colCount; col++) {
31 // A position is special if:
32 // 1. The element at this position is 1
33 // 2. The sum of its row is 1 (only this element is 1)
34 // 3. The sum of its column is 1 (only this element is 1)
35 if (mat[row][col] == 1 && rowSums[row] == 1 && colSums[col] == 1) {
36 specialCount++;
37 }
38 }
39 }
40
41 return specialCount;
42 }
43}
44
1class Solution {
2public:
3 int numSpecial(vector<vector<int>>& mat) {
4 // Get matrix dimensions
5 int numRows = mat.size();
6 int numCols = mat[0].size();
7
8 // Arrays to store the sum of each row and column
9 vector<int> rowSum(numRows, 0);
10 vector<int> colSum(numCols, 0);
11
12 // Calculate the sum of 1s in each row and column
13 for (int row = 0; row < numRows; ++row) {
14 for (int col = 0; col < numCols; ++col) {
15 rowSum[row] += mat[row][col];
16 colSum[col] += mat[row][col];
17 }
18 }
19
20 // Count special positions
21 int specialCount = 0;
22
23 // A position is special if:
24 // 1. The element at that position is 1
25 // 2. The sum of its row is 1 (only one 1 in the row)
26 // 3. The sum of its column is 1 (only one 1 in the column)
27 for (int row = 0; row < numRows; ++row) {
28 for (int col = 0; col < numCols; ++col) {
29 if (mat[row][col] == 1 && rowSum[row] == 1 && colSum[col] == 1) {
30 specialCount++;
31 }
32 }
33 }
34
35 return specialCount;
36 }
37};
38
1/**
2 * Counts the number of special positions in a binary matrix.
3 * A position (i, j) is special if mat[i][j] == 1 and all other elements
4 * in row i and column j are 0.
5 *
6 * @param mat - A binary matrix containing only 0s and 1s
7 * @returns The count of special positions in the matrix
8 */
9function numSpecial(mat: number[][]): number {
10 // Get matrix dimensions
11 const rowCount: number = mat.length;
12 const colCount: number = mat[0].length;
13
14 // Initialize arrays to store the sum of each row and column
15 const rowSums: number[] = Array(rowCount).fill(0);
16 const colSums: number[] = Array(colCount).fill(0);
17
18 // Calculate the sum of 1s in each row and column
19 for (let row = 0; row < rowCount; ++row) {
20 for (let col = 0; col < colCount; ++col) {
21 rowSums[row] += mat[row][col];
22 colSums[col] += mat[row][col];
23 }
24 }
25
26 // Count special positions
27 let specialCount: number = 0;
28
29 // Check each position in the matrix
30 for (let row = 0; row < rowCount; ++row) {
31 for (let col = 0; col < colCount; ++col) {
32 // A position is special if:
33 // 1. The value at this position is 1
34 // 2. The sum of its row is 1 (only this position has 1)
35 // 3. The sum of its column is 1 (only this position has 1)
36 if (mat[row][col] === 1 && rowSums[row] === 1 && colSums[col] === 1) {
37 ++specialCount;
38 }
39 }
40 }
41
42 return specialCount;
43}
44
Time and Space Complexity
Time Complexity: O(m × n)
where m
is the number of rows and n
is the number of columns in the matrix.
The algorithm consists of two passes through the entire matrix:
- First pass: Iterates through all
m × n
elements to calculate the sum of each row and column, takingO(m × n)
time. - Second pass: Iterates through all
m × n
elements again to check if each element meets the special criteria (element equals 1, row sum equals 1, column sum equals 1), takingO(m × n)
time.
Total time complexity: O(m × n) + O(m × n) = O(m × n)
Space Complexity: O(m + n)
where m
is the number of rows and n
is the number of columns.
The algorithm uses:
rows
array of sizem
to store the sum of each row:O(m)
spacecols
array of sizen
to store the sum of each column:O(n)
space- A constant amount of additional variables (
ans
, loop indices):O(1)
space
Total space complexity: O(m) + O(n) + O(1) = O(m + n)
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Condition Checking Order
A common mistake is checking if rows[i] == 1
and cols[j] == 1
without first verifying that mat[i][j] == 1
. This can lead to unnecessary condition evaluations for cells containing 0, though it won't affect correctness.
Pitfall Example:
# Inefficient - checks row/column sums even for 0 cells if rows[i] == 1 and cols[j] == 1 and mat[i][j] == 1: special_count += 1
Solution:
Always check mat[i][j] == 1
first as a short-circuit condition:
# Efficient - short-circuits for 0 cells if mat[i][j] == 1 and rows[i] == 1 and cols[j] == 1: special_count += 1
2. Attempting Single-Pass Solution
Some might try to identify special positions in a single pass while building the row/column sums, but this is impossible since you need complete row and column counts before determining if a position is special.
Pitfall Example:
# Wrong - trying to count special positions while building sums
for i in range(num_rows):
for j in range(num_cols):
if mat[i][j] == 1:
row_sums[i] += 1
col_sums[j] += 1
# Can't determine if special yet - counts incomplete!
if row_sums[i] == 1 and col_sums[j] == 1:
special_count += 1 # This won't work correctly
Solution: Stick to the two-pass approach - complete all counting first, then identify special positions.
3. Matrix Dimension Assumptions
Assuming the matrix is square or non-empty without checking can cause index errors.
Pitfall Example:
# Dangerous - assumes matrix is non-empty
num_cols = len(mat[0]) # IndexError if mat is empty
Solution: Add edge case handling:
if not mat or not mat[0]:
return 0
num_rows = len(mat)
num_cols = len(mat[0])
4. Misunderstanding "Special Position" Definition
Some might incorrectly think a position is special if it's the only 1 in either its row OR column (using OR instead of AND).
Pitfall Example:
# Wrong logic - uses OR instead of AND if mat[i][j] == 1 and (rows[i] == 1 or cols[j] == 1): special_count += 1
Solution: Remember that a special position must be the only 1 in BOTH its row AND column:
if mat[i][j] == 1 and rows[i] == 1 and cols[j] == 1: special_count += 1
Depth first search is equivalent to which of the tree traversal order?
Recommended Readings
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Runtime Overview When learning about algorithms and data structures you'll frequently encounter the term time complexity This concept is fundamental in computer science and offers insights into how long an algorithm takes to complete given a certain input size What is Time Complexity Time complexity represents the amount of time
Want a Structured Path to Master System Design Too? Don’t Miss This!