贪心
每次都改变一行或者一列,将0和1互换
若干次操作之后,按照每行的数统计结果,用二进制表示
首先高位的1会大于所有低位的1之和,如1000 = 8 > 0111 = 7
那么我们贪心的策略就有了,其次为了尽可能的构造高位1,对于第一列,如果翻转后1的个数多,那么就翻转,由于此时保证了最高位出现了最多的1,那么我们接下来依次检查每一行,如果这一行首尾不是0,那么就翻转这一行
然后我们用列变换再次检查其它列的元素,如果翻转后1变多,那么翻转列
总结一下策略
- 检查第一列,如果翻转后1变多,那么翻转
- 检查每一行,如果高位不是1,那么翻转
- 检查剩下的列(2到n),如果翻转后1变多,那么翻转
一道很好的贪心题目
class Solution:
def matrixScore(self, A: List[List[int]]) -> int:
# 行和列
row, col = len(A), len(A[0])
# 统计第一列的1
cnt = sum([A[i][0] for i in range(row)])
# 如果翻转后1变多
if cnt <= row // 2:
for i in range(row):
A[i][0] = 1 if A[i][0] == 0 else 0
# print(A)
# 对于每一行,如果第一个元素不是1,翻转这一行
for i in range(row):
if A[i][0] != 1:
for j in range(col):
A[i][j] = 1 if A[i][j] == 0 else 0
# print(A)
# 对于剩下的每一列,如果翻转后1变多,那么就翻转
for j in range(1, col):
cnt = sum([A[i][j] for i in range(row)])
if cnt <= row // 2:
for i in range(row):
A[i][j] = 1 if A[i][j] == 0 else 0
# print(A)
ans = 0
for i in range(row):
inx = 2
for j in range(col - 1, -1, -1):
ans += A[i][j] * (inx ** (col - j - 1))
return ans
再分析一下,我们要保证最高位都是1,那么第一步检查翻转列就是多余的,直接检查每一行即可
class Solution:
def matrixScore(self, A: List[List[int]]) -> int:
# 行和列
row, col = len(A), len(A[0])
# 对于每一行,如果第一个元素不是1,翻转这一行
for i in range(row):
if A[i][0] != 1:
for j in range(col):
A[i][j] = 1 if A[i][j] == 0 else 0
# print(A)
# 对于剩下的每一列,如果翻转后1变多,那么就翻转
for j in range(1, col):
cnt = sum([A[i][j] for i in range(row)])
if cnt <= row // 2:
for i in range(row):
A[i][j] = 1 if A[i][j] == 0 else 0
# print(A)
ans = 0
for i in range(row):
inx = 2
for j in range(col - 1, -1, -1):
ans += A[i][j] * (inx ** (col - j - 1))
return ans
不用移动矩阵的贪心
主要是贪心策略加上一些trick,直接用二进制的方法来统计每一位上1的贡献
class Solution {
public:
int matrixScore(vector<vector<int>>& A) {
int m = A.size(), n = A[0].size();
int ret = m * (1 << (n - 1));
for (int j = 1; j < n; j++) {
int nOnes = 0;
for (int i = 0; i < m; i++) {
if (A[i][0] == 1) {
nOnes += A[i][j];
} else {
nOnes += (1 - A[i][j]); // 如果这一行进行了行反转,则该元素的实际取值为 1 - A[i][j]
}
}
int k = max(nOnes, m - nOnes);
ret += k * (1 << (n - j - 1));
}
return ret;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/score-after-flipping-matrix/solution/fan-zhuan-ju-zhen-hou-de-de-fen-by-leetc-cxma/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
思想就是最大的矩阵第一列肯定都是1,然后直接加上首位的贡献,然后对于剩下的列,统计1的个数(如果首位是0,意味着这一行要反转,需要对应操作),然后我们用位移的方法加上每个1的贡献即可