2482. Difference Between Ones and Zeros in Row and Column
Problem Description
You are given a binary matrix grid
with dimensions m x n
(m rows and n columns) containing only 0s and 1s. Your task is to create a new matrix called diff
with the same dimensions, where each element is calculated using a specific formula based on the counts of 1s and 0s in the corresponding row and column.
For each position [i][j]
in the difference matrix, you need to:
- Count the number of 1s in row
i
(call thisonesRow[i]
) - Count the number of 1s in column
j
(call thisonesCol[j]
) - Count the number of 0s in row
i
(call thiszerosRow[i]
) - Count the number of 0s in column
j
(call thiszerosCol[j]
)
Then calculate: diff[i][j] = onesRow[i] + onesCol[j] - zerosRow[i] - zerosCol[j]
The solution approach first counts the number of 1s in each row and column. Since we know the total number of elements in each row is n
and in each column is m
, we can derive:
zerosRow[i] = n - onesRow[i]
(total columns minus ones in that row)zerosCol[j] = m - onesCol[j]
(total rows minus ones in that column)
The formula then simplifies to: diff[i][j] = onesRow[i] + onesCol[j] - (n - onesRow[i]) - (m - onesCol[j])
This can be further simplified to: diff[i][j] = 2 * onesRow[i] + 2 * onesCol[j] - n - m
The algorithm iterates through the grid once to count 1s in each row and column, then builds the difference matrix using these precomputed values, achieving an efficient O(m*n)
time complexity.
Intuition
The key insight is recognizing that we don't need to recalculate the counts for every single cell. If we look at the formula diff[i][j] = onesRow[i] + onesCol[j] - zerosRow[i] - zerosCol[j]
, we notice that for any cell in row i
, the values onesRow[i]
and zerosRow[i]
remain constant. Similarly, for any cell in column j
, the values onesCol[j]
and zerosCol[j]
stay the same.
This observation leads us to think about preprocessing: instead of counting 1s and 0s repeatedly for each cell, we can count them once for each row and column, then reuse these values.
Another crucial realization is that we don't need to separately count both 1s and 0s. Since each row has exactly n
elements and each column has exactly m
elements, if we know the count of 1s, we can immediately derive the count of 0s:
- Number of 0s in row
i
=n
- Number of 1s in rowi
- Number of 0s in column
j
=m
- Number of 1s in columnj
This relationship allows us to simplify our formula. If we let r
be the count of 1s in row i
and c
be the count of 1s in column j
, then:
onesRow[i] = r
onesCol[j] = c
zerosRow[i] = n - r
zerosCol[j] = m - c
Substituting into the original formula:
diff[i][j] = r + c - (n - r) - (m - c) = 2r + 2c - n - m
This transformation shows us that we only need to track the count of 1s for each row and column, making the solution both simpler and more efficient. We can compute all row and column counts in a single pass through the matrix, then construct the difference matrix using these precomputed values in a second pass.
Solution Approach
The implementation follows a two-pass approach using arrays to store precomputed counts:
Step 1: Initialize Storage Arrays We create two arrays to store the count of 1s:
rows
array of sizem
to store the count of 1s in each rowcols
array of sizen
to store the count of 1s in each column
Step 2: Count 1s in Single Pass
We iterate through the entire grid once. For each cell grid[i][j]
:
- If the value is 1, we increment both
rows[i]
andcols[j]
- This is done efficiently by adding the cell value directly:
rows[i] += v
andcols[j] += v
for i, row in enumerate(grid):
for j, v in enumerate(row):
rows[i] += v # Add 1 if cell is 1, add 0 if cell is 0
cols[j] += v
Step 3: Build the Difference Matrix
We create a new m x n
matrix diff
and populate it using our precomputed counts. For each position [i][j]
:
r
represents the count of 1s in rowi
c
represents the count of 1s in columnj
- Apply the simplified formula:
diff[i][j] = r + c - (n - r) - (m - c)
diff = [[0] * n for _ in range(m)]
for i, r in enumerate(rows):
for j, c in enumerate(cols):
diff[i][j] = r + c - (n - r) - (m - c)
The formula r + c - (n - r) - (m - c)
effectively calculates:
r
(ones in row i) +c
(ones in column j)- minus
(n - r)
(zeros in row i) - minus
(m - c)
(zeros in column j)
Time Complexity: O(m * n)
- We traverse the grid twice, once for counting and once for building the result.
Space Complexity: O(m + n)
for the auxiliary arrays (not counting the output matrix).
This approach is optimal because we must examine every cell at least once to get the counts, and we must fill every cell in the output matrix, giving us a lower bound of O(m * n)
time.
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 a small example to illustrate the solution approach.
Given grid:
grid = [[0, 1, 1], [1, 0, 1], [0, 0, 0]]
Step 1: Count 1s in each row and column
First pass through the grid:
-
Row 0: [0, 1, 1] → contains 2 ones →
rows[0] = 2
-
Row 1: [1, 0, 1] → contains 2 ones →
rows[1] = 2
-
Row 2: [0, 0, 0] → contains 0 ones →
rows[2] = 0
-
Column 0: [0, 1, 0] → contains 1 one →
cols[0] = 1
-
Column 1: [1, 0, 0] → contains 1 one →
cols[1] = 1
-
Column 2: [1, 1, 0] → contains 2 ones →
cols[2] = 2
So we have:
rows = [2, 2, 0]
cols = [1, 1, 2]
m = 3
(number of rows)n = 3
(number of columns)
Step 2: Calculate diff matrix using the formula
For each position [i][j], we apply: diff[i][j] = rows[i] + cols[j] - (n - rows[i]) - (m - cols[j])
Position [0][0]:
rows[0] = 2
,cols[0] = 1
diff[0][0] = 2 + 1 - (3 - 2) - (3 - 1) = 3 - 1 - 2 = 0
Position [0][1]:
rows[0] = 2
,cols[1] = 1
diff[0][1] = 2 + 1 - (3 - 2) - (3 - 1) = 3 - 1 - 2 = 0
Position [0][2]:
rows[0] = 2
,cols[2] = 2
diff[0][2] = 2 + 2 - (3 - 2) - (3 - 2) = 4 - 1 - 1 = 2
Position [1][0]:
rows[1] = 2
,cols[0] = 1
diff[1][0] = 2 + 1 - (3 - 2) - (3 - 1) = 3 - 1 - 2 = 0
Position [1][1]:
rows[1] = 2
,cols[1] = 1
diff[1][1] = 2 + 1 - (3 - 2) - (3 - 1) = 3 - 1 - 2 = 0
Position [1][2]:
rows[1] = 2
,cols[2] = 2
diff[1][2] = 2 + 2 - (3 - 2) - (3 - 2) = 4 - 1 - 1 = 2
Position [2][0]:
rows[2] = 0
,cols[0] = 1
diff[2][0] = 0 + 1 - (3 - 0) - (3 - 1) = 1 - 3 - 2 = -4
Position [2][1]:
rows[2] = 0
,cols[1] = 1
diff[2][1] = 0 + 1 - (3 - 0) - (3 - 1) = 1 - 3 - 2 = -4
Position [2][2]:
rows[2] = 0
,cols[2] = 2
diff[2][2] = 0 + 2 - (3 - 0) - (3 - 2) = 2 - 3 - 1 = -2
Final Result:
diff = [[ 0, 0, 2], [ 0, 0, 2], [-4, -4, -2]]
This example demonstrates how we avoid redundant counting by precomputing the row and column sums once, then efficiently calculating each cell in the difference matrix using the simplified formula.
Solution Implementation
1class Solution:
2 def onesMinusZeros(self, grid: List[List[int]]) -> List[List[int]]:
3 # Get dimensions of the grid
4 num_rows, num_cols = len(grid), len(grid[0])
5
6 # Initialize arrays to store count of ones in each row and column
7 ones_in_row = [0] * num_rows
8 ones_in_col = [0] * num_cols
9
10 # Count ones in each row and column
11 for row_idx, row in enumerate(grid):
12 for col_idx, value in enumerate(row):
13 ones_in_row[row_idx] += value
14 ones_in_col[col_idx] += value
15
16 # Initialize the difference matrix
17 diff_matrix = [[0] * num_cols for _ in range(num_rows)]
18
19 # Calculate difference for each cell
20 # Formula: ones_in_row[i] + ones_in_col[j] - zeros_in_row[i] - zeros_in_col[j]
21 # Where zeros_in_row[i] = num_cols - ones_in_row[i]
22 # And zeros_in_col[j] = num_rows - ones_in_col[j]
23 for row_idx, row_ones_count in enumerate(ones_in_row):
24 for col_idx, col_ones_count in enumerate(ones_in_col):
25 diff_matrix[row_idx][col_idx] = (
26 row_ones_count + col_ones_count -
27 (num_cols - row_ones_count) -
28 (num_rows - col_ones_count)
29 )
30
31 return diff_matrix
32
1class Solution {
2 public int[][] onesMinusZeros(int[][] grid) {
3 // Get dimensions of the grid
4 int numRows = grid.length;
5 int numCols = grid[0].length;
6
7 // Arrays to store count of ones in each row and column
8 int[] onesInRow = new int[numRows];
9 int[] onesInCol = new int[numCols];
10
11 // Count the number of ones in each row and column
12 for (int row = 0; row < numRows; row++) {
13 for (int col = 0; col < numCols; col++) {
14 int cellValue = grid[row][col];
15 onesInRow[row] += cellValue;
16 onesInCol[col] += cellValue;
17 }
18 }
19
20 // Create the difference matrix
21 int[][] differenceMatrix = new int[numRows][numCols];
22
23 // Calculate difference for each cell:
24 // diff[i][j] = onesRow[i] + onesCol[j] - zerosRow[i] - zerosCol[j]
25 for (int row = 0; row < numRows; row++) {
26 for (int col = 0; col < numCols; col++) {
27 int zerosInRow = numCols - onesInRow[row];
28 int zerosInCol = numRows - onesInCol[col];
29
30 differenceMatrix[row][col] = onesInRow[row] + onesInCol[col]
31 - zerosInRow - zerosInCol;
32 }
33 }
34
35 return differenceMatrix;
36 }
37}
38
1class Solution {
2public:
3 vector<vector<int>> onesMinusZeros(vector<vector<int>>& grid) {
4 // Get dimensions of the grid
5 int numRows = grid.size();
6 int numCols = grid[0].size();
7
8 // Count the number of ones in each row and column
9 vector<int> onesInRow(numRows, 0);
10 vector<int> onesInCol(numCols, 0);
11
12 // Single pass to count ones in rows and columns
13 for (int row = 0; row < numRows; ++row) {
14 for (int col = 0; col < numCols; ++col) {
15 int cellValue = grid[row][col];
16 onesInRow[row] += cellValue;
17 onesInCol[col] += cellValue;
18 }
19 }
20
21 // Initialize result matrix
22 vector<vector<int>> result(numRows, vector<int>(numCols));
23
24 // Calculate the difference for each cell
25 // Formula: onesInRow[i] + onesInCol[j] - zerosInRow[i] - zerosInCol[j]
26 // Where zerosInRow[i] = numCols - onesInRow[i] and zerosInCol[j] = numRows - onesInCol[j]
27 for (int row = 0; row < numRows; ++row) {
28 for (int col = 0; col < numCols; ++col) {
29 int zerosInRow = numCols - onesInRow[row];
30 int zerosInCol = numRows - onesInCol[col];
31
32 result[row][col] = onesInRow[row] + onesInCol[col] - zerosInRow - zerosInCol;
33 }
34 }
35
36 return result;
37 }
38};
39
1/**
2 * Calculates the difference matrix where each cell contains:
3 * (number of 1s in row i) + (number of 1s in column j) - (number of 0s in row i) - (number of 0s in column j)
4 * @param grid - Input binary matrix containing only 0s and 1s
5 * @returns Difference matrix with calculated values for each position
6 */
7function onesMinusZeros(grid: number[][]): number[][] {
8 const rowCount: number = grid.length;
9 const columnCount: number = grid[0].length;
10
11 // Arrays to store count of 1s in each row and column
12 const onesInRows: number[] = new Array(rowCount).fill(0);
13 const onesInColumns: number[] = new Array(columnCount).fill(0);
14
15 // Count the number of 1s in each row and column
16 for (let row: number = 0; row < rowCount; row++) {
17 for (let col: number = 0; col < columnCount; col++) {
18 if (grid[row][col] === 1) {
19 onesInRows[row]++;
20 onesInColumns[col]++;
21 }
22 }
23 }
24
25 // Initialize result matrix with same dimensions as input
26 const resultMatrix: number[][] = Array.from(
27 { length: rowCount },
28 () => new Array<number>(columnCount).fill(0)
29 );
30
31 // Calculate the difference value for each cell
32 // Formula: onesRow[i] + onesCol[j] - zerosRow[i] - zerosCol[j]
33 // Which simplifies to: onesRow[i] + onesCol[j] - (rowCount - onesRow[i]) - (columnCount - onesCol[j])
34 for (let row: number = 0; row < rowCount; row++) {
35 for (let col: number = 0; col < columnCount; col++) {
36 const zerosInRow: number = rowCount - onesInRows[row];
37 const zerosInColumn: number = columnCount - onesInColumns[col];
38
39 resultMatrix[row][col] = onesInRows[row] + onesInColumns[col] - zerosInRow - zerosInColumn;
40 }
41 }
42
43 return resultMatrix;
44}
45
Time and Space Complexity
Time Complexity: O(m × n)
The algorithm consists of two main phases:
- First nested loop: Iterates through all
m × n
elements of the grid to calculate row sums and column sums. This takesO(m × n)
time. - Second nested loop: Iterates through all
m
rows andn
columns to compute the difference matrix. This also takesO(m × n)
time.
Since both phases are sequential (not nested with each other), the total time complexity is O(m × n) + O(m × n) = O(m × n)
.
Space Complexity: O(m + n)
(excluding the output array)
The algorithm uses:
rows
array of sizem
to store row sums:O(m)
spacecols
array of sizen
to store column sums:O(n)
spacediff
matrix of sizem × n
for the output:O(m × n)
space
Following the reference answer's convention of ignoring the space used by the answer (the diff
matrix), the space complexity is O(m) + O(n) = O(m + n)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrectly Calculating Zeros Count
A common mistake is trying to count zeros separately or miscalculating the relationship between ones and zeros.
Incorrect approach:
# Wrong: Counting zeros separately (inefficient and error-prone)
zeros_in_row = [0] * num_rows
zeros_in_col = [0] * num_cols
for i, row in enumerate(grid):
for j, value in enumerate(row):
if value == 0:
zeros_in_row[i] += 1
zeros_in_col[j] += 1
Correct approach:
# Right: Derive zeros from ones count zeros_in_row[i] = num_cols - ones_in_row[i] zeros_in_col[j] = num_rows - ones_in_col[j]
2. Confusion Between Row and Column Dimensions
Mixing up m
(number of rows) and n
(number of columns) when calculating zeros is a frequent error.
Incorrect:
# Wrong: Using num_rows for row zeros calculation diff_matrix[i][j] = ( row_ones + col_ones - (num_rows - row_ones) - # Should be num_cols! (num_cols - col_ones) # Should be num_rows! )
Correct:
# Right: Row has num_cols elements, column has num_rows elements diff_matrix[i][j] = ( row_ones + col_ones - (num_cols - row_ones) - # Zeros in row i (num_rows - col_ones) # Zeros in column j )
3. Modifying Input Grid Instead of Creating New Matrix
Some might try to modify the input grid in-place to save space, which changes the original data.
Incorrect:
# Wrong: Modifying input grid
for i in range(num_rows):
for j in range(num_cols):
grid[i][j] = calculation_result # Destroys original data
return grid
Correct:
# Right: Create new matrix
diff_matrix = [[0] * num_cols for _ in range(num_rows)]
# ... populate diff_matrix
return diff_matrix
4. Off-by-One Errors in Formula Application
Forgetting to subtract or add certain components of the formula.
Incorrect:
# Wrong: Missing subtraction or using wrong signs diff_matrix[i][j] = row_ones + col_ones + zeros_in_row + zeros_in_col # Or diff_matrix[i][j] = row_ones - col_ones - zeros_in_row - zeros_in_col
Correct:
# Right: Proper formula application diff_matrix[i][j] = ( ones_in_row[i] + ones_in_col[j] - zeros_in_row[i] - zeros_in_col[j] )
5. Inefficient Matrix Initialization
Using append operations instead of pre-allocating the matrix size.
Inefficient:
# Suboptimal: Building matrix row by row
diff_matrix = []
for i in range(num_rows):
row = []
for j in range(num_cols):
row.append(calculated_value)
diff_matrix.append(row)
Efficient:
# Better: Pre-allocate matrix
diff_matrix = [[0] * num_cols for _ in range(num_rows)]
# Then fill in values
Prevention Tips:
- Always clarify what represents rows vs columns (m vs n)
- Use descriptive variable names that indicate what they count
- Double-check the mathematical relationship:
zeros = total - ones
- Test with simple examples where you can manually verify the calculation
- Remember that row
i
hasn
elements and columnj
hasm
elements
Which of the following array represent a max heap?
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!