Every day a Leetcode
题目来源:861. 翻转矩阵后的得分
解法1:贪心
对于二进制数来说,我们只要保证最高位是1,就可以保证这个数是最大的,因为移动操作会使得它取反,因此我们进行行变化的时候只需要考虑首位即可。
遍历每行,如果该行的第一个元素不是1,就对该行元素取反。
对于后面的列处理,由于只影响的是该列,所以若要取得最大值,只需要保证该列1的个数不少于0的个数即可。
遍历每列(注意第一列除外!),记录该列0的个数为 cntZero,如果 cntZero > m - cntZero,则对该列元素取反。
最后求出每行二进制数的十进制表示,累加求和即为答案。
代码:
/*
* @lc app=leetcode.cn id=861 lang=cpp
*
* [861] 翻转矩阵后的得分
*/
// @lc code=start
class Solution
{
public:
int matrixScore(vector<vector<int>> &grid)
{
int m = grid.size(), n = m ? grid[0].size() : 0;
// 按行反转
for (int i = 0; i < m; i++)
if (grid[i][0] == 0)
for (int j = 0; j < n; j++)
grid[i][j] = grid[i][j] ? 0 : 1;
// 按列反转
for (int j = 1; j < n; j++)
{
int cntZero = 0;
for (int i = 0; i < m; i++)
if (grid[i][j] == 0)
cntZero++;
if (cntZero > m - cntZero)
for (int i = 0; i < m; i++)
grid[i][j] = grid[i][j] ? 0 : 1;
}
// 求和
int sum = 0;
for (int i = 0; i < m; i++)
{
int num = 0, mult = 1;
for (int j = n - 1; j >= 0; j--)
{
num += grid[i][j] * mult;
mult *= 2;
}
sum += num;
}
return sum;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(m*n),其中 m 和 n 分别是矩阵 grid 的行数和列数。
空间复杂度:O(1)。