问题描述
有一个二维矩阵 A 其中每个元素的值为 0 或 1 。
移动是指选择任一行或列,并转换该行或列中的每一个值:将所有 0 都更改为 1,将所有 1 都更改为 0。
在做出任意次数的移动后,将该矩阵的每一行都按照二进制数来解释,矩阵的得分就是这些数字的总和。
返回尽可能高的分数。
示例:
输入:[[0,0,1,1],[1,0,1,0],[1,1,0,0]]
输出:39
解释:
转换为 [[1,1,1,1],[1,0,0,1],[1,1,1,1]]
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
提示:
1 <= A.length <= 20
1 <= A[0].length <= 20
A[i][j] 是 0 或 1
分析:
对于一个翻转序列 S = { r 1 , r 2 , . . . , r n } S=\{ r_1, r_2, ... , r_n \} S={r1,r2,...,rn}其中 r_i 为第i次翻转操作,为列翻转或行翻转。
交换:
交换任意两个翻转操作,结果不变。
对序列S转换为S’,将S中所有行变换提前。即S’为先进行行变换,后列变换。
目标:使得2进制表示的值最大
- 对于一个变换序列S,如果变换后矩阵第一列存在0:如果将首位为0的行进行变换,则会使得计算结果更大。
因此,对于要使得最终计算结果最大,矩阵第一列一定全转换为1.
- 对于一个列变换,如果列变换后该列的1的数目增多,则计算结果更大。
操作流程:
- 使用行变换将矩阵的第一列转换为全1
- 使用列变换将矩阵的其他列变为1的数目多于一半
解题思路
算法
input: mat
output: sum
// row exchange
for row in mat:
if row[0] == 1 :
exchange( row )
// col exchange
for col in mat:
count = col.sum
if count <= col.size()/2
exchange( col )
// val calculate
sum = 0
for row in mat :
sum += row.val
数据结构
不用使用额外的数据结构