LeetCode 翻转矩阵后的得分(贪心策略)

有一个二维矩阵 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

思 路 分 析 : \color{blue}思路分析: 这道题说白了就是让我们计算矩阵所有元素的和,并且每个元素是有一定的权重。
LeetCode 翻转矩阵后的得分(贪心策略)_第1张图片
并且可知每一行的第一个元素的权重最大,且由于二进制的特征,最高位的1权值会超过低位所有权值的和,比如“11111”,最高位的’1’代表24 = 16,第四位"1111" = 2 3 + 2 2 + 2 1 + 20 = 15。

因此我们首先需要保证第一列(每一行的第一个元素)都为1,
我们第一步判断每一行的第一个元素是否是1,如果不是1,则将这一行的所有元素进行翻转;
第二步:尽量保证剩余列中1的个数竟可能多。

class Solution {
public:
    int matrixScore(vector<vector<int>>& A) {
        int sumRes = 0;
        int rowSize = A.size(), colSize = A[0].size();
        //首先保证第一列全部为1
        for (int row = 0; row < rowSize; ++row){
            if (A[row][0] != 1){
                //如果这一行的第一个元素不为1,则翻转这一行
                for (int col = 0; col < colSize; ++col){
                    A[row][col] = 1 - A[row][col];
                }
            }
        }
        //第一列全为1,所以可以直接求第一列的权值和
        sumRes += rowSize * pow(2, colSize - 1);
        //再使其他列中1的个数尽可能多
        for (int col = 1; col < colSize; ++col){
            int oneCount = 0;//统计这一列1的个数
            for (int row = 0; row < rowSize; ++row){
                oneCount += A[row][col];
            }
            if (oneCount * 2 >= rowSize){
                //如果1的个数不少于一般,则这一列不需要翻转
                sumRes += oneCount * pow(2, colSize - col - 1);
            }
            else{
                //否则将计算这一列进行翻转之后1的个数的权值和
                sumRes += (rowSize - oneCount) * pow(2, colSize - col - 1);
            }
        }
        return sumRes;
    }
};

LeetCode 翻转矩阵后的得分(贪心策略)_第2张图片

你可能感兴趣的:(LeetCode,贪心算法,数组)