【LetMeFly】1072.按列翻转得到最大值等行数
力扣题目链接:https://leetcode.cn/problems/flip-columns-for-maximum-number-of-equal-rows/
给定 m x n
矩阵 matrix
。
你可以从中选出任意数量的列并翻转其上的 每个 单元格。(即翻转后,单元格的值从 0
变成 1
,或者从 1
变为 0
。)
返回 经过一些翻转后,行与行之间所有值都相等的最大行数 。
示例 1:
输入:matrix = [[0,1],[1,1]] 输出:1 解释:不进行翻转,有 1 行所有值都相等。
示例 2:
输入:matrix = [[0,1],[1,0]] 输出:2 解释:翻转第一列的值之后,这两行都由相等的值组成。
示例 3:
输入:matrix = [[0,0,0],[0,0,1],[1,1,0]] 输出:2 解释:翻转前两列的值之后,后两行由相等的值组成。
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] == 0
或1
方法一:思维
首先这道题的中文描述有点错误。题目要求的是:一行之内的元素全相等 的 行数 的最大值。
怎么个翻转法呢?我可以选取某些列,将这些列的0变成1,1变成0。
试想这样(完全相同)的多行:
011010
011010
011010
...
我们只需要把第2、3、5列翻转,就能得到:
000000
000000
000000
...
这些原本完全相同的行,每一行都变成了0
试想这样(完全相反)的两行:
011010
100101
我们只需要把第2、3、5列翻转,就能得到:
000000
111111
这些完全相反的行,有的变成了全0,有的变成了全1
有没有发现,上面两种情况,我们都是反转的第“2,3,5”行,最终得到的结果是:这些行要么全0,要么全1
也就是说:原本完全相同或完全相反的行,可以通过题目描述的翻转操作,使得这些行变得要么全0要么全1
而题目问的,就是“全0行”和“全1行”的最大行数和
因此,我们只需要将完全相同的行 或 完全相反的行 聚成一类,最大的“聚合块”的大小即为答案。
例如:
0 0 0
1 1 1
0 0 0
0 1 0
1 1 1
0 0 1
1 1 0
可以聚合成三块:
1. [0, 0, 0], [1, 1, 1], [0, 0, 0], [1, 1, 1]
2. [0, 1, 0]
3. [0, 0, 1], [1, 1, 0]
第1块最大有四个即为答案。
因此剩下的问题就是:如何将完全相同的行或完全相反的行聚成一类?(现在完全不用考虑题目说的什么翻转,什么相等了)
不失一般性,我们可以让每一行的第一个元素全部变成0。
- 如果某一行第一个元素本来就是0,那么这一行就完全不变
- 否则(某行第一个元素是1),就将这一行的每个元素都翻转(0变1,1变0)
注意这里的翻转和题目中的翻转没有任何关系,这里翻转只是为了将完全相反的行变成完全相同的行从而用来统计
这样,问题就变成了:将完全相同的行聚成一类,最大的“聚合块”的大小是多少
使用一个哈希表就能很方便地解决了。
- 时间复杂度 O ( n × m ) O(n\times m) O(n×m),其中 m a t r i x matrix matrix的大小为 n × m n\times m n×m
- 空间复杂度 O ( n × m ) O(n\times m) O(n×m)
AC代码
C++
class Solution {
public:
int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
unordered_map<vector<bool>, int> ma; // 哈希表
int n = matrix.size(), m = matrix[0].size();
int ans = 0;
for (int i = 0; i < n; i++) {
vector<bool> thisLine(m); // 这一行
for (int j = 0; j < m; j++) {
// 使用异或操作,[行首, 本元素] -> 最终结果:[0, 0] -> 0,[0, 1] -> 1,[1, 0] -> 1,[1, 1] -> 0
thisLine[j] = matrix[i][j] ^ matrix[i][0];
}
ma[thisLine]++;
ans = max(ans, ma[thisLine]);
}
return ans;
}
};
Python
# from typing import List
# from collections import defaultdict
class Solution:
def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
ma = defaultdict(int)
n, m = len(matrix), len(matrix[0])
ans = 0
for i in range(n):
thisLine = ''
for j in range(m):
thisLine += chr(ord('0') + matrix[i][j] ^ matrix[i][0])
ma[thisLine] += 1
ans = max(ans, ma[thisLine])
return ans
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/130680800