from collections import Counter
from typing import List
class Solution:
def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
patterns = Counter()
for row in matrix:
# Normalize: flip the row if the first element is 1
# So all rows start with 0 (by flipping columns as needed)
first = row[0]
normalized = tuple(x ^ first for x in row)
patterns[normalized] += 1
return max(patterns.values())
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
class Solution {
public:
int maxEqualRowsAfterFlips(vector<vector<int>>& matrix) {
unordered_map<string, int> patterns;
for (auto& row : matrix) {
string pattern;
int first = row[0];
for (int x : row) {
pattern += (x ^ first) + '0';
}
patterns[pattern]++;
}
int res = 0;
for (auto& p : patterns) {
res = max(res, p.second);
}
return res;
}
};
import java.util.*;
class Solution {
public int maxEqualRowsAfterFlips(int[][] matrix) {
Map<String, Integer> patterns = new HashMap<>();
for (int[] row : matrix) {
int first = row[0];
StringBuilder sb = new StringBuilder();
for (int x : row) {
sb.append(x ^ first);
}
String key = sb.toString();
patterns.put(key, patterns.getOrDefault(key, 0) + 1);
}
int res = 0;
for (int count : patterns.values()) {
res = Math.max(res, count);
}
return res;
}
}
/**
* @param {number[][]} matrix
* @return {number}
*/
var maxEqualRowsAfterFlips = function(matrix) {
let patterns = new Map();
for (let row of matrix) {
let first = row[0];
let norm = row.map(x => x ^ first).join(',');
patterns.set(norm, (patterns.get(norm) || 0) + 1);
}
let res = 0;
for (let count of patterns.values()) {
res = Math.max(res, count);
}
return res;
};
matrix
of size m x n
, you are allowed to flip any columns (i.e., for any column, you can flip all values in that column). After flipping any set of columns any number of times, you want to maximize the number of rows that are exactly the same (i.e., all elements in the row are equal for those rows). The task is to return the maximum number of rows that can be made equal after any number of column flips.
1 <= matrix.length, matrix[0].length <= 300
matrix
is 0 or 1.n
columns, there are 2^n
possible flip combinations, which is not feasible for large n
.
Instead, let's think about the effect of flipping columns: flipping a column inverts all entries in that column for every row. Our goal is for as many rows as possible to become identical after flipping some columns.
If two rows can be made the same by flipping some columns, then for each column where they differ, we can flip that column to make them match. So, for each row, the set of columns we would need to flip to make it all zeros (or all ones) is unique.
Rather than brute-force every flip, we can represent each row by the pattern of differences compared to a base row (for example, the first row). Rows that can be made the same will have the same pattern after normalization. Thus, the problem reduces to finding the most common "normalized" row pattern.
We use a hash map because it allows O(1) time insertion and lookup for each pattern, making the solution efficient.
Suppose matrix = [[0,1],[1,0],[1,1]]
.
Now, our patterns are:
2^n
column flips, and for each, comparing all rows. This is O(2^n * m * n), which is infeasible for n up to 300.The key insight is that, rather than examining every possible set of column flips, we can "normalize" each row so that all rows that could be made equal by flipping columns will have the same normalized pattern. By counting the frequency of each pattern, we efficiently determine the largest group of rows that can be made identical. This approach is both elegant and efficient, reducing the problem from exponential to linear time with respect to the matrix size.