{x}
blog image

Score After Flipping Matrix

You are given an m x n binary matrix grid.

A move consists of choosing any row or column and toggling each value in that row or column (i.e., changing all 0's to 1's, and all 1's to 0's).

Every row of the matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers.

Return the highest possible score after making any number of moves (including zero moves).

 

Example 1:

Input: grid = [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation: 0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39

Example 2:

Input: grid = [[0]]
Output: 1

 

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 20
  • grid[i][j] is either 0 or 1.

Solution Explanation:

The problem asks to find the maximum possible score after flipping rows and columns in a binary matrix. Each row represents a binary number, and the score is the sum of these binary numbers. Flipping a row or column inverts all the bits (0s become 1s and vice-versa).

The solution uses a greedy approach. The core idea is to optimize the score by strategically flipping rows and columns. It leverages the fact that flipping a row doesn't affect the relative values of bits within that row; it only impacts the overall sum.

Algorithm:

  1. Row Flipping: First, iterate through each row. If the first element of a row is 0, flip the entire row. This ensures that the most significant bit (MSB) of every row is 1. This is a crucial step to maximizing the score, as it contributes the most value to the binary number represented by each row.

  2. Column Optimization: Next, iterate through each column. For each column, count the number of 1s (cnt). The optimal strategy is to choose the larger between cnt and m - cnt (where m is the number of rows). This is because flipping a column toggles 0s and 1s; choosing the larger number guarantees a higher contribution to the final score for that column's bit position.

  3. Score Calculation: Finally, calculate the overall score. For each column, the contribution to the score is the chosen larger count (max(cnt, m - cnt)) multiplied by the weight of that bit position (2 raised to the power of its position from the right).

Time and Space Complexity:

  • Time Complexity: O(m * n), where 'm' is the number of rows and 'n' is the number of columns. This is because we iterate through the matrix twice: once for row flipping and once for column optimization.
  • Space Complexity: O(1). The algorithm operates in-place and doesn't use extra space proportional to the input size.

Code Explanation (Python):

class Solution:
    def matrixScore(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        for i in range(m):
            if grid[i][0] == 0:
                for j in range(n):
                    grid[i][j] ^= 1  # Flip the bit (XOR with 1)
 
        ans = 0
        for j in range(n):
            cnt = sum(grid[i][j] for i in range(m))
            ans += max(cnt, m - cnt) * (1 << (n - j - 1)) # Calculate contribution from this column
        return ans
 

The code directly implements the algorithm described above. grid[i][j] ^= 1 is a concise way to flip a bit using the XOR operator. 1 << (n - j - 1) efficiently calculates 2 raised to the power of the bit position. The rest of the code handles iteration and score calculation as explained in the algorithm. The other languages' codes follow the same logic and differ only in syntax.