Daily LeetCode 861. Score After Flipping Matrix

https://leetcode.com/problems/score-after-flipping-matrix/

Medium

问题描述:

We have a two dimensional matrix A where each value is 0 or 1.

A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0s to 1s, and all 1s to 0s.

After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers.

Return the highest possible score.

Example 1:

1
2
3
4
5
Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation:
Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]].
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39

Note:

  1. 1 <= A.length <= 20
  2. 1 <= A[0].length <= 20
  3. A[i][j] is 0 or 1.

题目分析及代码:

给定一个矩阵A,我们可以对矩阵的行或列进行取反操作,要求操作完成后,把每一行当作二进制数,得到的和最大。

了解二进制就能明白,想要确保一个二进制数足够大,那么首先要确保该二进制数的首位为1,在这个题目中,我们先对矩阵的行进行处理,反转所有首位为0的行;再对列进行处理,对列处理时,我们不再关注首位的情况,我们关注一列中0和1的个数,这是因为最终的计算是看行的,列中1的数量多,那么总和自然更大。

以Example 1为例:

我们先对行进行处理,由于首位均为1,因此不变:
$$
A=\left[\begin{array}{ccc}
1,&1,&0,&0\
1,&0,&1,&0\
1,&1,&0,&0
\end{array}\right]
$$
接着,我们对列进行处理,反转第三列和第四列:
$$
A=\left[\begin{array}{ccc}
1,&1,&1,&1\
1,&0,&0,&1\
1,&1,&1,&1
\end{array}\right]
$$
代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from collections import Counter

class Solution:
def matrixScore(self, A: List[List[int]]) -> int:
for i in range(len(A)):
if A[i][0] == 0:
A[i] = [0 if A[i][_] == 1 else 1 for _ in range(len(A[i]))]

for i in range(len(A[0])):
column = [col[i] for col in A]
counter = Counter(column)
if counter[0] > counter[1]:
column = [0 if column[_] == 1 else 1 for _ in range(len(column))]
for r in range(len(A)):
A[r][i] = column[r]

res = 0
for row in A:
row.reverse()
for i in range(len(A[0])):
res += (2 ** i) * row[i]

return res