给定
m x n
矩阵matrix
。你可以从中选出任意数量的列并翻转其上的 每个 单元格。(即翻转后,单元格的值从
0
变成1
,或者从1
变为0
。)返回 经过一些翻转后,行与行之间所有值都相等的最大行数 。
这是一道比较有意思的贪心算法问题。我们可以枚举所有可能的翻转方案,并对每个方案进行判断。具体来说,我们可以针对每一行,计算其翻转后得到的 01 串,然后将所有行的 01 串进行分类,找到其中个数最多的一类,这些行的值就是相等的。最后统计相等行的数量即可。
以下是 C++ 实现代码:
#include<vector>
#include<unordered_map>
#include <algorithm>
using namespace std;
class Solution {
public:
int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
unordered_map<string, int> counter;
int res = 0;
for (auto& row : matrix) {
string s1, s2;
for (int num : row) {
s1.push_back(num + '0');
s2.push_back((1+num)%2 + '0');
}
counter[s1]++;
counter[s2]++;
res = max(res, counter[s1]);
res = max(res, counter[s2]);
}
return res;
}
};
在这个实现中,我们使用哈希表 counter
来统计每种 01 串出现的个数,其中一个 01 串就是每个数的值相同或者相反。在遍历每一行时,我们计算出两个 01 串 s1
和 s2
,并将它们在 counter
中的计数器都加 1。然后更新结果变量 res
。
需要特别说明的是,由于 01 串具有相反对称性,当一个元素统计在 s1
中时,其值对应的元素必须统计在 s2
中。否则,如果只统计到 s1
中,那么当那些值与第一个元素相反的行向量出现时,它们的 s2
是相同的,但是这些行向量与第一个向量不一样,会导致结果不正确。
int main() {
//vector<vector<int> > matrix = { {0, 1},{1, 1} };
vector<vector<int> > matrix = { {0, 1},{1, 0} };
Solution so;
int res = so.maxEqualRowsAfterFlips(matrix);
return 0;
};