You are given an m x n
binary matrix grid
. You can perform two types of operations any number of times:
After performing any number of these operations, the score of the matrix is calculated by interpreting each row as a binary number and summing them all up. For example, the row [1,0,1]
is treated as binary 101
, which is 5
in decimal.
Your task is to return the highest possible score you can achieve after performing any number of flips.
Constraints:
grid[i][j]
is 0 or 1
At first glance, it seems we could try all possible combinations of row and column flips to maximize the sum. However, with up to 20 rows and 20 columns, this brute-force approach would be far too slow, as there are 2^(m+n)
possible flip combinations.
To optimize, we need to recognize patterns that maximize the binary value of each row. Since the leftmost bit in binary contributes the most to the number's value, we should prioritize making the first column all 1s. Once the first column is set, we can consider each subsequent column and decide if flipping it increases the total score.
The key insight is: For each row, we can always flip it so its first element is 1. Then, for each column, we can flip it if doing so increases the count of 1s in that column.
This approach ensures that every bit position in every row is maximized, starting from the most significant bit (leftmost column) to the least significant.
Input:
grid = [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
O(2^{m+n} \cdot m \cdot n)
time, which is infeasible for large m
and n
.
O(m \cdot n)
O(n \cdot m)
O(m \cdot n)
O(m \cdot n)
O(1)
if we modify in place, or O(m \cdot n)
if we use a copy.
The optimal strategy for maximizing the score after flipping a binary matrix is to:
class Solution:
def matrixScore(self, grid):
m, n = len(grid), len(grid[0])
# Step 1: Flip rows so first column is all 1s
for i in range(m):
if grid[i][0] == 0:
for j in range(n):
grid[i][j] ^= 1
# Step 2: For each column, flip if more 0s than 1s
for j in range(1, n):
ones = sum(grid[i][j] for i in range(m))
if ones < m - ones:
for i in range(m):
grid[i][j] ^= 1
# Step 3: Calculate total score
score = 0
for row in grid:
num = 0
for bit in row:
num = (num << 1) | bit
score += num
return score
class Solution {
public:
int matrixScore(vector<vector<int>>& grid) {
int m = grid.size(), n = grid[0].size();
// Step 1: Flip rows so first column is all 1s
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 0) {
for (int j = 0; j < n; ++j) {
grid[i][j] ^= 1;
}
}
}
// Step 2: For each column, flip if more 0s than 1s
for (int j = 1; j < n; ++j) {
int ones = 0;
for (int i = 0; i < m; ++i) {
ones += grid[i][j];
}
if (ones < m - ones) {
for (int i = 0; i < m; ++i) {
grid[i][j] ^= 1;
}
}
}
// Step 3: Calculate total score
int score = 0;
for (int i = 0; i < m; ++i) {
int num = 0;
for (int j = 0; j < n; ++j) {
num = (num << 1) | grid[i][j];
}
score += num;
}
return score;
}
};
class Solution {
public int matrixScore(int[][] grid) {
int m = grid.length, n = grid[0].length;
// Step 1: Flip rows so first column is all 1s
for (int i = 0; i < m; ++i) {
if (grid[i][0] == 0) {
for (int j = 0; j < n; ++j) {
grid[i][j] ^= 1;
}
}
}
// Step 2: For each column, flip if more 0s than 1s
for (int j = 1; j < n; ++j) {
int ones = 0;
for (int i = 0; i < m; ++i) {
ones += grid[i][j];
}
if (ones < m - ones) {
for (int i = 0; i < m; ++i) {
grid[i][j] ^= 1;
}
}
}
// Step 3: Calculate total score
int score = 0;
for (int i = 0; i < m; ++i) {
int num = 0;
for (int j = 0; j < n; ++j) {
num = (num << 1) | grid[i][j];
}
score += num;
}
return score;
}
}
var matrixScore = function(grid) {
const m = grid.length, n = grid[0].length;
// Step 1: Flip rows so first column is all 1s
for (let i = 0; i < m; ++i) {
if (grid[i][0] === 0) {
for (let j = 0; j < n; ++j) {
grid[i][j] ^= 1;
}
}
}
// Step 2: For each column, flip if more 0s than 1s
for (let j = 1; j < n; ++j) {
let ones = 0;
for (let i = 0; i < m; ++i) {
ones += grid[i][j];
}
if (ones < m - ones) {
for (let i = 0; i < m; ++i) {
grid[i][j] ^= 1;
}
}
}
// Step 3: Calculate total score
let score = 0;
for (let i = 0; i < m; ++i) {
let num = 0;
for (let j = 0; j < n; ++j) {
num = (num << 1) | grid[i][j];
}
score += num;
}
return score;
};