LeetCode 1582 - Special Positions in a Binary Matrix
Here is a complete, detailed technical solution guide for LeetCode 1582 - Special Positions in a Binary Matrix, followin
Difficulty: 🟢 Easy
Topics: Array, Matrix
Solution
Here is a complete, detailed technical solution guide for LeetCode 1582 - Special Positions in a Binary Matrix, following your formatting and content requirements precisely.
Problem Understanding
The problem provides an m x n binary matrix mat consisting only of 0s and 1s, and asks us to find the number of special positions. A position (i, j) is special if mat[i][j] == 1 and all other elements in row i and column j are 0. In other words, a 1 is special if it is the only 1 in its row and its column.
The input constraints are 1 <= m, n <= 100, which tells us the matrix is relatively small and that a simple O(m × n × max(m, n)) brute-force solution might work but is inefficient. The output is a single integer representing the total number of special positions.
Edge cases to consider include: matrices with all zeros (should return 0), matrices where all ones lie in the same row or column (none are special), or a matrix with a single element (either 0 or 1). The problem guarantees that the matrix contains only 0s and 1s, so we do not need to handle other data types.
Approaches
Brute Force Approach:
The simplest approach is to iterate over each cell (i, j). For every 1 found, scan the entire row i and column j to ensure there are no other 1s. If both checks pass, the position is special.
This approach works because it directly implements the definition, but it is inefficient. For each 1, we may scan up to m + n elements, leading to a worst-case complexity of O(m × n × (m + n)) if almost all elements are 1. This is unnecessary given the input size.
Optimal Approach:
The key insight is that for a position (i, j) to be special, its entire row and column must contain exactly one 1. We can precompute the number of ones in each row and each column using two arrays: row_count and col_count. After counting, we iterate over the matrix, and any position (i, j) where mat[i][j] == 1, row_count[i] == 1, and col_count[j] == 1 is special.
This approach is efficient because counting rows and columns takes O(m × n) time and checking each element afterward takes another O(m × n), resulting in an overall O(m × n) time complexity. Space complexity is O(m + n) for the two count arrays.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(m × n × (m + n)) | O(1) | Scan each row and column for each 1 |
| Optimal | O(m × n) | O(m + n) | Precompute row and column counts, then check conditions |
Algorithm Walkthrough
- Initialize two arrays,
row_countof sizemandcol_countof sizen, to store the number of ones in each row and column, respectively. - Iterate over each cell
(i, j)in the matrix. Ifmat[i][j] == 1, incrementrow_count[i]andcol_count[j]. This counts the total number of ones per row and per column. - Initialize a counter
special_positionsto 0. - Iterate over the matrix again. For each cell
(i, j)wheremat[i][j] == 1, check ifrow_count[i] == 1andcol_count[j] == 1. If both conditions are true, incrementspecial_positions. - Return
special_positions.
Why it works:
By counting the number of ones in each row and column upfront, we reduce the problem to a simple check per cell. Any 1 with a unique row and column count is guaranteed to be the only 1 in its row and column, fulfilling the special position condition.
Python Solution
from typing import List
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
# Count ones in each row and column
for i in range(m):
for j in range(n):
if mat[i][j] == 1:
row_count[i] += 1
col_count[j] += 1
special_positions = 0
# Check for special positions
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:
special_positions += 1
return special_positions
Explanation:
The first nested loop counts the number of ones in each row and column. The second nested loop checks the condition for a special position by leveraging the precomputed counts. Using arrays for counting ensures we do not repeatedly scan rows or columns, which keeps the time complexity optimal.
Go Solution
func numSpecial(mat [][]int) int {
m, n := len(mat), len(mat[0])
rowCount := make([]int, m)
colCount := make([]int, n)
// Count ones in each row and column
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if mat[i][j] == 1 {
rowCount[i]++
colCount[j]++
}
}
}
specialPositions := 0
// Check for special positions
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
if mat[i][j] == 1 && rowCount[i] == 1 && colCount[j] == 1 {
specialPositions++
}
}
}
return specialPositions
}
Go-specific Notes:
In Go, slices are used for the rowCount and colCount arrays. Indexing and iteration are similar to Python. There is no need to handle nil matrices because the problem constraints guarantee at least 1 row and 1 column.
Worked Examples
Example 1: mat = [[1,0,0],[0,0,1],[1,0,0]]
Step 1: Count ones:
| Row | Count |
|---|---|
| 0 | 1 |
| 1 | 1 |
| 2 | 1 |
| Col | Count |
|---|---|
| 0 | 2 |
| 1 | 0 |
| 2 | 1 |
Step 2: Check special positions:
- (0,0) → row_count[0]=1, col_count[0]=2 → not special
- (1,2) → row_count[1]=1, col_count[2]=1 → special
- (2,0) → row_count[2]=1, col_count[0]=2 → not special
Result = 1
Example 2: mat = [[1,0,0],[0,1,0],[0,0,1]]
Row counts: [1,1,1]
Column counts: [1,1,1]
All diagonal positions (0,0), (1,1), (2,2) satisfy the condition → result = 3
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(m × n) | Count ones in rows and columns (O(m × n)) and check conditions (O(m × n)) |
| Space | O(m + n) | Arrays to store row counts and column counts |
This complexity is optimal given that every element must be examined at least once. Memory usage is minimal, only two arrays proportional to the number of rows and columns.
Test Cases
# Provided examples
assert Solution().numSpecial([[1,0,0],[0,0,1],[1,0,0]]) == 1 # only (1,2)
assert Solution().numSpecial([[1,0,0],[0,1,0],[0,0,1]]) == 3 # diagonal
# Edge cases
assert Solution().numSpecial([[0]]) == 0 # single element zero
assert Solution().numSpecial([[1]]) == 1 # single element one
assert Solution().numSpecial([[1,1],[1,0]]) == 0 # multiple ones in row/column
# Larger test
assert Solution().numSpecial([[0,1,0],[0,0,0],[0,0,1]]) == 2 # (0,1) and (2,2)
| Test | Why |
|---|---|
[[1,0,0],[0,0,1],[1,0,0]] |
Example with overlapping column ones |
[[1,0,0],[0,1,0],[0,0,1]] |
Diagonal ones, all special |
[[0]] |
Minimum size, zero |
| `[[1 |