【贪心】861. 翻转矩阵后的得分
题目:
有一个二维矩阵 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.
可以先进行行变换将每行的第一个元素变为1,再对除第0列外的所有列进行列变换,使得每个列经过变换后有最多的1;
在处理中,可以不修改A[][]数组。
假设第一列已经为全1,对第2....n列,计算其中1的个数。
如果相应行的第1列元素A[i][0] == 1,则A[i][j]中'1'是‘1’,‘0'是'0'
否则,A[i][j]中'1'记作‘0’,‘0'记作'1'
对结果的计算在遍历的过程中逐渐算出
res 初始时为 m*(1<<(n-1)) 是每一行第一列对应值的和
res在每遍历完一个列后就会更新其值 :
int k = Math.max(cntOne,m-cntOne); res +=k*(1<<(n-i-1));
class Solution { public int matrixScore(int[][] A) { int m = A.length, n = A[0].length; int res = m*(1<<(n-1)); for(int i = 1;i<n;i++){ int cntOne = 0; for(int j = 0;j<m;j++){ if(A[j][0] == 1){ cntOne +=A[j][i]; }else{ cntOne +=1-A[j][i]; } }
//找到当前列经过变换后最多的1的个数 int k = Math.max(cntOne,m-cntOne); res +=k*(1<<(n-i-1)); } return res; } }

浙公网安备 33010602011771号