0%

1072. 按列翻转得到最大值等行数

1072.按列翻转得到最大值等行数

题目描述:

给定 $n \times m$ 矩阵matrix,从中选出任意数量的列并翻转其上的每个单元格。(翻转后,单元格的值从 $0$ 变成 $1$ ,或者从 $1$ 变成 $0$ 。)经过一些翻转之后,行内所有值都相等的最大的行数。(全为 $0$ ,或全为 $1$ 的最大行数)

数据范围:

$1\le m, n \le 300$

题解:

注意题目说的是行内值相等,不是两行完全相等。也就是说相等的或者互补的通过翻转之后会得到行内值相等的行,每一行都进行翻转与不翻转使用 $hash$ 记录相等的个数,得到答案。

优化一下,对行内第一个字符为 $0$ 的不翻转,为 $0$ 的翻转,然后使用 $hash$ 记录最大值。

也可以使用 vector<bool>,这个数据类型带压缩,可以直接 $hash$ ,也可以调用 .flip() 翻转。

  • .flip:可以翻转该 vector<bool>
  • .swap:交换两个位置的元素。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
unordered_map<string, int> mp;
int maxEqualRowsAfterFlips(vector<vector<int>> &matrix)
{
int n = matrix.size(), m = matrix[0].size(), ans = 0;
for (int i = 0; i < n; ++i)
{
string s(m, 0);

for (int j = 0; j < m; ++j)
{
s[j] = (matrix[i][j] ^ matrix[i][0]) + '0';
}
ans = max(ans, ++mp[s]);
}
return ans;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
const static int maxn = 1e5 + 10;
const static int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
unordered_map<vector<bool>, int> mp;
int maxEqualRowsAfterFlips(vector<vector<int>> &matrix)
{
int n = matrix.size(), m = matrix[0].size(), ans = 0;
for (int i = 0; i < n; ++i)
{
vector<bool> tmp(matrix[i].begin(), matrix[i].end());
if (tmp[0])
tmp.flip();
ans = max(ans, ++mp[tmp]);
}
return ans;
}
};