Skip to content

Commit 341b63c

Browse files
committed
feat: add solutions to lc problem: No.1072
No.1072: Flip Columns For Maximum Number of Equal Rows
1 parent b3d9353 commit 341b63c

File tree

7 files changed

+126
-94
lines changed

7 files changed

+126
-94
lines changed

solution/1000-1099/1072.Flip Columns For Maximum Number of Equal Rows/README.md

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,22 @@
5757

5858
**方法一:哈希表**
5959

60+
我们观察发现,如果矩阵中的两行满足以下条件之一,则它们可以通过翻转某些列的方式得到相等的行:
61+
62+
1. 两行的对应位置元素相等,即如果其中一行元素为 $1,0,0,1$,则另一行元素也为 $1,0,0,1$;
63+
1. 两行的对应位置元素相反,即如果其中一行元素为 $1,0,0,1$,则另一行元素为 $0,1,1,0$。
64+
65+
我们称满足以上条件之一的两行元素为“等价行”,那么题目所求的答案即为矩阵中最多包含等价行的行数。
66+
67+
因此,我们可以遍历矩阵的每一行,将每一行转换成第一个元素为 $0$ 的“等价行”。具体做法如下:
68+
69+
- 如果当前行的第一个元素为 $0$,那么当前行的元素保持不变;
70+
- 如果当前行的第一个元素为 $1$,那么我们将当前行的每个元素进行翻转,即 $0$ 变成 $1$, $1$ 变成 $0$。也就是说,我们将以 $1$ 开头的行翻转成以 $0$ 开头的“等价行”。
71+
72+
这样一来,我们只需要用一个哈希表来统计转换后的每一行的出现次数,其中键为转换后的行(可以将所有数字拼接成一个字符串),值为该行出现的次数。最后,哈希表中值的最大值即为矩阵中最多包含等价行的行数。
73+
74+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
75+
6076
<!-- tabs:start -->
6177

6278
### **Python3**
@@ -68,13 +84,8 @@ class Solution:
6884
def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
6985
cnt = Counter()
7086
for row in matrix:
71-
t = []
72-
for v in row:
73-
if row[0] == 1:
74-
v ^= 1
75-
t.append(str(v))
76-
s = ''.join(t)
77-
cnt[s] += 1
87+
t = tuple(row) if row[0] == 0 else tuple(x ^ 1 for x in row)
88+
cnt[t] += 1
7889
return max(cnt.values())
7990
```
8091

@@ -85,21 +96,16 @@ class Solution:
8596
```java
8697
class Solution {
8798
public int maxEqualRowsAfterFlips(int[][] matrix) {
88-
Map<String, Integer> map = new HashMap<>();
89-
for (int[] row : matrix) {
90-
if (row[0] == 1) {
91-
for (int i = 0; i < row.length; ++i) {
92-
row[i] ^= 1;
93-
}
94-
}
95-
StringBuilder sb = new StringBuilder();
99+
Map<String, Integer> cnt = new HashMap<>();
100+
int ans = 0;
101+
for (var row : matrix) {
102+
var sb = new StringBuilder();
96103
for (int x : row) {
97-
sb.append(x);
104+
sb.append(row[0] == 0 ? x : x ^ 1);
98105
}
99-
String s = sb.toString();
100-
map.put(s, map.getOrDefault(s, 0) + 1);
106+
ans = Math.max(ans, cnt.merge(sb.toString(), 1, Integer::sum));
101107
}
102-
return map.values().stream().max(Integer::compareTo).get();
108+
return ans;
103109
}
104110
}
105111
```
@@ -113,13 +119,11 @@ public:
113119
unordered_map<string, int> cnt;
114120
int ans = 0;
115121
for (auto& row : matrix) {
116-
string s = "";
117-
for (int v : row) {
118-
if (row[0] == 1) v ^= 1;
119-
s += to_string(v);
122+
string s;
123+
for (int x : row) {
124+
s.push_back('0' + (row[0] == 0 ? x : x ^ 1));
120125
}
121-
++cnt[s];
122-
ans = max(ans, cnt[s]);
126+
ans = max(ans, ++cnt[s]);
123127
}
124128
return ans;
125129
}
@@ -129,22 +133,21 @@ public:
129133
### **Go**
130134
131135
```go
132-
func maxEqualRowsAfterFlips(matrix [][]int) int {
133-
ans := 0
136+
func maxEqualRowsAfterFlips(matrix [][]int) (ans int) {
134137
cnt := map[string]int{}
135138
for _, row := range matrix {
136139
s := []byte{}
137-
for _, v := range row {
140+
for _, x := range row {
138141
if row[0] == 1 {
139-
v ^= 1
142+
x ^= 1
140143
}
141-
s = append(s, byte(v+'0'))
144+
s = append(s, byte(x)+'0')
142145
}
143146
t := string(s)
144147
cnt[t]++
145148
ans = max(ans, cnt[t])
146149
}
147-
return ans
150+
return
148151
}
149152
150153
func max(a, b int) int {
@@ -155,6 +158,26 @@ func max(a, b int) int {
155158
}
156159
```
157160

161+
### **TypeScript**
162+
163+
```ts
164+
function maxEqualRowsAfterFlips(matrix: number[][]): number {
165+
const cnt = new Map<string, number>();
166+
let ans = 0;
167+
for (const row of matrix) {
168+
if (row[0] === 1) {
169+
for (let i = 0; i < row.length; i++) {
170+
row[i] ^= 1;
171+
}
172+
}
173+
const s = row.join('');
174+
cnt.set(s, (cnt.get(s) || 0) + 1);
175+
ans = Math.max(ans, cnt.get(s)!);
176+
}
177+
return ans;
178+
}
179+
```
180+
158181
### **...**
159182

160183
```

solution/1000-1099/1072.Flip Columns For Maximum Number of Equal Rows/README_EN.md

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,8 @@ class Solution:
5656
def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
5757
cnt = Counter()
5858
for row in matrix:
59-
t = []
60-
for v in row:
61-
if row[0] == 1:
62-
v ^= 1
63-
t.append(str(v))
64-
s = ''.join(t)
65-
cnt[s] += 1
59+
t = tuple(row) if row[0] == 0 else tuple(x ^ 1 for x in row)
60+
cnt[t] += 1
6661
return max(cnt.values())
6762
```
6863

@@ -71,21 +66,16 @@ class Solution:
7166
```java
7267
class Solution {
7368
public int maxEqualRowsAfterFlips(int[][] matrix) {
74-
Map<String, Integer> map = new HashMap<>();
75-
for (int[] row : matrix) {
76-
if (row[0] == 1) {
77-
for (int i = 0; i < row.length; ++i) {
78-
row[i] ^= 1;
79-
}
80-
}
81-
StringBuilder sb = new StringBuilder();
69+
Map<String, Integer> cnt = new HashMap<>();
70+
int ans = 0;
71+
for (var row : matrix) {
72+
var sb = new StringBuilder();
8273
for (int x : row) {
83-
sb.append(x);
74+
sb.append(row[0] == 0 ? x : x ^ 1);
8475
}
85-
String s = sb.toString();
86-
map.put(s, map.getOrDefault(s, 0) + 1);
76+
ans = Math.max(ans, cnt.merge(sb.toString(), 1, Integer::sum));
8777
}
88-
return map.values().stream().max(Integer::compareTo).get();
78+
return ans;
8979
}
9080
}
9181
```
@@ -99,13 +89,11 @@ public:
9989
unordered_map<string, int> cnt;
10090
int ans = 0;
10191
for (auto& row : matrix) {
102-
string s = "";
103-
for (int v : row) {
104-
if (row[0] == 1) v ^= 1;
105-
s += to_string(v);
92+
string s;
93+
for (int x : row) {
94+
s.push_back('0' + (row[0] == 0 ? x : x ^ 1));
10695
}
107-
++cnt[s];
108-
ans = max(ans, cnt[s]);
96+
ans = max(ans, ++cnt[s]);
10997
}
11098
return ans;
11199
}
@@ -115,22 +103,21 @@ public:
115103
### **Go**
116104
117105
```go
118-
func maxEqualRowsAfterFlips(matrix [][]int) int {
119-
ans := 0
106+
func maxEqualRowsAfterFlips(matrix [][]int) (ans int) {
120107
cnt := map[string]int{}
121108
for _, row := range matrix {
122109
s := []byte{}
123-
for _, v := range row {
110+
for _, x := range row {
124111
if row[0] == 1 {
125-
v ^= 1
112+
x ^= 1
126113
}
127-
s = append(s, byte(v+'0'))
114+
s = append(s, byte(x)+'0')
128115
}
129116
t := string(s)
130117
cnt[t]++
131118
ans = max(ans, cnt[t])
132119
}
133-
return ans
120+
return
134121
}
135122
136123
func max(a, b int) int {
@@ -141,6 +128,26 @@ func max(a, b int) int {
141128
}
142129
```
143130

131+
### **TypeScript**
132+
133+
```ts
134+
function maxEqualRowsAfterFlips(matrix: number[][]): number {
135+
const cnt = new Map<string, number>();
136+
let ans = 0;
137+
for (const row of matrix) {
138+
if (row[0] === 1) {
139+
for (let i = 0; i < row.length; i++) {
140+
row[i] ^= 1;
141+
}
142+
}
143+
const s = row.join('');
144+
cnt.set(s, (cnt.get(s) || 0) + 1);
145+
ans = Math.max(ans, cnt.get(s)!);
146+
}
147+
return ans;
148+
}
149+
```
150+
144151
### **...**
145152

146153
```

solution/1000-1099/1072.Flip Columns For Maximum Number of Equal Rows/Solution.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@ class Solution {
44
unordered_map<string, int> cnt;
55
int ans = 0;
66
for (auto& row : matrix) {
7-
string s = "";
8-
for (int v : row) {
9-
if (row[0] == 1) v ^= 1;
10-
s += to_string(v);
7+
string s;
8+
for (int x : row) {
9+
s.push_back('0' + (row[0] == 0 ? x : x ^ 1));
1110
}
12-
++cnt[s];
13-
ans = max(ans, cnt[s]);
11+
ans = max(ans, ++cnt[s]);
1412
}
1513
return ans;
1614
}

solution/1000-1099/1072.Flip Columns For Maximum Number of Equal Rows/Solution.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
1-
func maxEqualRowsAfterFlips(matrix [][]int) int {
2-
ans := 0
1+
func maxEqualRowsAfterFlips(matrix [][]int) (ans int) {
32
cnt := map[string]int{}
43
for _, row := range matrix {
54
s := []byte{}
6-
for _, v := range row {
5+
for _, x := range row {
76
if row[0] == 1 {
8-
v ^= 1
7+
x ^= 1
98
}
10-
s = append(s, byte(v+'0'))
9+
s = append(s, byte(x)+'0')
1110
}
1211
t := string(s)
1312
cnt[t]++
1413
ans = max(ans, cnt[t])
1514
}
16-
return ans
15+
return
1716
}
1817

1918
func max(a, b int) int {
Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
class Solution {
22
public int maxEqualRowsAfterFlips(int[][] matrix) {
3-
Map<String, Integer> map = new HashMap<>();
4-
for (int[] row : matrix) {
5-
if (row[0] == 1) {
6-
for (int i = 0; i < row.length; ++i) {
7-
row[i] ^= 1;
8-
}
9-
}
10-
StringBuilder sb = new StringBuilder();
3+
Map<String, Integer> cnt = new HashMap<>();
4+
int ans = 0;
5+
for (var row : matrix) {
6+
var sb = new StringBuilder();
117
for (int x : row) {
12-
sb.append(x);
8+
sb.append(row[0] == 0 ? x : x ^ 1);
139
}
14-
String s = sb.toString();
15-
map.put(s, map.getOrDefault(s, 0) + 1);
10+
ans = Math.max(ans, cnt.merge(sb.toString(), 1, Integer::sum));
1611
}
17-
return map.values().stream().max(Integer::compareTo).get();
12+
return ans;
1813
}
19-
}
14+
}

solution/1000-1099/1072.Flip Columns For Maximum Number of Equal Rows/Solution.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@ class Solution:
22
def maxEqualRowsAfterFlips(self, matrix: List[List[int]]) -> int:
33
cnt = Counter()
44
for row in matrix:
5-
t = []
6-
for v in row:
7-
if row[0] == 1:
8-
v ^= 1
9-
t.append(str(v))
10-
s = ''.join(t)
11-
cnt[s] += 1
5+
t = tuple(row) if row[0] == 0 else tuple(x ^ 1 for x in row)
6+
cnt[t] += 1
127
return max(cnt.values())
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function maxEqualRowsAfterFlips(matrix: number[][]): number {
2+
const cnt = new Map<string, number>();
3+
let ans = 0;
4+
for (const row of matrix) {
5+
if (row[0] === 1) {
6+
for (let i = 0; i < row.length; i++) {
7+
row[i] ^= 1;
8+
}
9+
}
10+
const s = row.join('');
11+
cnt.set(s, (cnt.get(s) || 0) + 1);
12+
ans = Math.max(ans, cnt.get(s)!);
13+
}
14+
return ans;
15+
}

0 commit comments

Comments
 (0)