LeetCode: 861. Score After Flipping Matrix
LeetCode: 861. Score After Flipping Matrix
题目描述
We have a two dimensional matrix A
where each value is 0
or 1
.
A move consists of choosing any row or column, and toggling each value in that row or column: changing all 0
s to 1
s, and all 1
s to 0
s.
After making any number of moves, every row of this matrix is interpreted as a binary number, and the score of the matrix is the sum of these numbers.
Return the highest possible score.
Example 1:
Input: [[0,0,1,1],[1,0,1,0],[1,1,0,0]]
Output: 39
Explanation:
Toggled to [[1,1,1,1],[1,0,0,1],[1,1,1,1]].
0b1111 + 0b1001 + 0b1111 = 15 + 9 + 15 = 39
Note:
1 <= A.length <= 20
1 <= A[0].length <= 20
A[i][j] is 0 or 1.
解题思路 —— 贪心思想
- 每一行的第一个数字代表二进制的最高位,因此,首先需要翻转行,以使该位为
1
。 - 每一列的
1
的权重(即转换为二进制后的值)是一致的,因此为了使得和最大,我们需要翻转列,使得每一列的1
的个数大于0
的个数。 对样例分析。
初始状态:
[0,0,1,1] [1,0,1,0] [1,1,0,0]
首列置为 1:
[1,1,0,0] [1,0,1,0] [1,1,0,0]
每一列 1 的个数大于 0 的个数:
[1,1,1,1] [1,0,0,1] [1,1,1,1]
计算结果:
15 + 9 + 15 = 39
.
AC 代码
class Solution {
// 翻转列
void FlipColumn(vector<vector<int>>& A, int col)
{
for(size_t i = 0; i < A.size(); ++i)
{
A[i][col] = !A[i][col];
}
}
// 翻转行
void FlipRow(vector<vector<int>>& A, int row)
{
for(size_t i = 0; i < A[row].size(); ++i)
{
A[row][i] = !A[row][i];
}
}
// 计算列 1 的个数
int CntColOne(vector<vector<int>>& A, int col)
{
int cnt = 0;
for(size_t i = 0; i < A.size(); ++i)
{
cnt += A[i][col];
}
return cnt;
}
// 计算行的二进制值
int NumRow(vector<vector<int>>& A, int row)
{
int ans = 0;
for(int x : A[row]) ans = (ans << 1)+x;
return ans;
}
public:
int matrixScore(vector<vector<int>>& A) {
if(A.empty()) return 0;
// 首列置为 1
for(size_t i = 0; i < A.size(); ++i)
{
if(A[i][0] == 0)
{
FlipRow(A, i);
}
}
// 每列 1 的个数大于 0 的个数
for(size_t i = 0; i < A[0].size(); ++i)
{
if(CntColOne(A, i)*2 < A.size())
{
FlipColumn(A, i);
}
}
// 计算二进制值得和
int ans = 0;
for(size_t i = 0; i < A.size(); ++i)
{
ans += NumRow(A, i);
}
return ans;
}
};