【贪心】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; } }

 

posted @ 2020-12-08 01:20  3KBLACK  阅读(61)  评论(0)    收藏  举报