Skip to content

Commit b8c5c54

Browse files
committed
feat: add solutions to lc problem: No.2123
No.2123.Minimum Operations to Remove Adjacent Ones in Matrix
1 parent 0d0ef59 commit b8c5c54

File tree

7 files changed

+678
-5
lines changed

7 files changed

+678
-5
lines changed

solution/2100-2199/2123.Minimum Operations to Remove Adjacent Ones in Matrix/README.md

+236-4
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,262 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54+
**方法一:匈牙利算法**
55+
56+
我们注意到,如果矩阵中的两个 $1$ 相邻,那么它们一定属于不同的组。因此,我们可以把矩阵中所有的 $1$ 视为点,相邻的两个 $1$ 之间连一条边,构建二分图。
57+
58+
那么,问题可以转化为求二分图最小点覆盖,也即选出最少数目的点来覆盖所有的边。由于二分图的最小点覆盖数等于最大匹配数,因此我们可以使用匈牙利算法求出二分图的最大匹配数。
59+
60+
匈牙利算法的核心思想是,不断地从未匹配的点出发,寻找增广路径,直到没有增广路径为止,就得到了最大匹配。
61+
62+
时间复杂度 $O(m \times n)$,其中 $n$ 和 $m$ 分别是矩阵中 $1$ 的数目以及边的数目。
63+
5464
<!-- tabs:start -->
5565

5666
### **Python3**
5767

5868
<!-- 这里可写当前语言的特殊实现逻辑 -->
5969

6070
```python
61-
71+
class Solution:
72+
def minimumOperations(self, grid: List[List[int]]) -> int:
73+
def find(i: int) -> int:
74+
for j in g[i]:
75+
if j not in vis:
76+
vis.add(j)
77+
if match[j] == -1 or find(match[j]):
78+
match[j] = i
79+
return 1
80+
return 0
81+
82+
g = defaultdict(list)
83+
m, n = len(grid), len(grid[0])
84+
for i, row in enumerate(grid):
85+
for j, v in enumerate(row):
86+
if (i + j) % 2 and v:
87+
x = i * n + j
88+
if i < m - 1 and grid[i + 1][j]:
89+
g[x].append(x + n)
90+
if i and grid[i - 1][j]:
91+
g[x].append(x - n)
92+
if j < n - 1 and grid[i][j + 1]:
93+
g[x].append(x + 1)
94+
if j and grid[i][j - 1]:
95+
g[x].append(x - 1)
96+
97+
match = [-1] * (m * n)
98+
ans = 0
99+
for i in g.keys():
100+
vis = set()
101+
ans += find(i)
102+
return ans
62103
```
63104

64105
### **Java**
65106

66107
<!-- 这里可写当前语言的特殊实现逻辑 -->
67108

68109
```java
110+
class Solution {
111+
private Map<Integer, List<Integer>> g = new HashMap<>();
112+
private Set<Integer> vis = new HashSet<>();
113+
private int[] match;
114+
115+
public int minimumOperations(int[][] grid) {
116+
int m = grid.length, n = grid[0].length;
117+
for (int i = 0; i < m; ++i) {
118+
for (int j = 0; j < n; ++j) {
119+
if ((i + j) % 2 == 1 && grid[i][j] == 1) {
120+
int x = i * n + j;
121+
if (i < m - 1 && grid[i + 1][j] == 1) {
122+
g.computeIfAbsent(x, z -> new ArrayList<>()).add(x + n);
123+
}
124+
if (i > 0 && grid[i - 1][j] == 1) {
125+
g.computeIfAbsent(x, z -> new ArrayList<>()).add(x - n);
126+
}
127+
if (j < n - 1 && grid[i][j + 1] == 1) {
128+
g.computeIfAbsent(x, z -> new ArrayList<>()).add(x + 1);
129+
}
130+
if (j > 0 && grid[i][j - 1] == 1) {
131+
g.computeIfAbsent(x, z -> new ArrayList<>()).add(x - 1);
132+
}
133+
}
134+
}
135+
}
136+
match = new int[m * n];
137+
Arrays.fill(match, -1);
138+
int ans = 0;
139+
for (int i : g.keySet()) {
140+
ans += find(i);
141+
vis.clear();
142+
}
143+
return ans;
144+
}
145+
146+
private int find(int i) {
147+
for (int j : g.get(i)) {
148+
if (vis.add(j)) {
149+
if (match[j] == -1 || find(match[j]) == 1) {
150+
match[j] = i;
151+
return 1;
152+
}
153+
}
154+
}
155+
return 0;
156+
}
157+
}
158+
```
69159

160+
### **C++**
161+
162+
```cpp
163+
class Solution {
164+
public:
165+
int minimumOperations(vector<vector<int>>& grid) {
166+
int m = grid.size(), n = grid[0].size();
167+
vector<int> match(m * n, -1);
168+
unordered_set<int> vis;
169+
unordered_map<int, vector<int>> g;
170+
for (int i = 0; i < m; ++i) {
171+
for (int j = 0; j < n; ++j) {
172+
if ((i + j) % 2 && grid[i][j]) {
173+
int x = i * n + j;
174+
if (i < m - 1 && grid[i + 1][j]) {
175+
g[x].push_back(x + n);
176+
}
177+
if (i && grid[i - 1][j]) {
178+
g[x].push_back(x - n);
179+
}
180+
if (j < n - 1 && grid[i][j + 1]) {
181+
g[x].push_back(x + 1);
182+
}
183+
if (j && grid[i][j - 1]) {
184+
g[x].push_back(x - 1);
185+
}
186+
}
187+
}
188+
}
189+
int ans = 0;
190+
function<int(int)> find = [&](int i) -> int {
191+
for (int& j : g[i]) {
192+
if (!vis.count(j)) {
193+
vis.insert(j);
194+
if (match[j] == -1 || find(match[j])) {
195+
match[j] = i;
196+
return 1;
197+
}
198+
}
199+
}
200+
return 0;
201+
};
202+
for (auto& [i, _] : g) {
203+
ans += find(i);
204+
vis.clear();
205+
}
206+
return ans;
207+
}
208+
};
70209
```
71210
72-
### **TypeScript**
211+
### **Go**
212+
213+
```go
214+
func minimumOperations(grid [][]int) (ans int) {
215+
m, n := len(grid), len(grid[0])
216+
vis := map[int]bool{}
217+
match := make([]int, m*n)
218+
for i := range match {
219+
match[i] = -1
220+
}
221+
g := map[int][]int{}
222+
for i, row := range grid {
223+
for j, v := range row {
224+
if (i+j)&1 == 1 && v == 1 {
225+
x := i*n + j
226+
if i < m-1 && grid[i+1][j] == 1 {
227+
g[x] = append(g[x], x+n)
228+
}
229+
if i > 0 && grid[i-1][j] == 1 {
230+
g[x] = append(g[x], x-n)
231+
}
232+
if j < n-1 && grid[i][j+1] == 1 {
233+
g[x] = append(g[x], x+1)
234+
}
235+
if j > 0 && grid[i][j-1] == 1 {
236+
g[x] = append(g[x], x-1)
237+
}
238+
}
239+
}
240+
}
241+
var find func(int) int
242+
find = func(i int) int {
243+
for _, j := range g[i] {
244+
if !vis[j] {
245+
vis[j] = true
246+
if match[j] == -1 || find(match[j]) == 1 {
247+
match[j] = i
248+
return 1
249+
}
250+
}
251+
}
252+
return 0
253+
}
254+
for i := range g {
255+
ans += find(i)
256+
vis = map[int]bool{}
257+
}
258+
return
259+
}
260+
```
73261

74-
<!-- 这里可写当前语言的特殊实现逻辑 -->
262+
### **TypeScript**
75263

76264
```ts
77-
265+
function minimumOperations(grid: number[][]): number {
266+
const m = grid.length;
267+
const n = grid[0].length;
268+
const match: number[] = Array(m * n).fill(-1);
269+
const vis: Set<number> = new Set();
270+
const g: Map<number, number[]> = new Map();
271+
for (let i = 0; i < m; ++i) {
272+
for (let j = 0; j < n; ++j) {
273+
if ((i + j) % 2 && grid[i][j]) {
274+
const x = i * n + j;
275+
g.set(x, []);
276+
if (i < m - 1 && grid[i + 1][j]) {
277+
g.get(x)!.push(x + n);
278+
}
279+
if (i && grid[i - 1][j]) {
280+
g.get(x)!.push(x - n);
281+
}
282+
if (j < n - 1 && grid[i][j + 1]) {
283+
g.get(x)!.push(x + 1);
284+
}
285+
if (j && grid[i][j - 1]) {
286+
g.get(x)!.push(x - 1);
287+
}
288+
}
289+
}
290+
}
291+
const find = (i: number): number => {
292+
for (const j of g.get(i)!) {
293+
if (!vis.has(j)) {
294+
vis.add(j);
295+
if (match[j] === -1 || find(match[j])) {
296+
match[j] = i;
297+
return 1;
298+
}
299+
}
300+
}
301+
return 0;
302+
};
303+
let ans = 0;
304+
for (const i of g.keys()) {
305+
ans += find(i);
306+
vis.clear();
307+
}
308+
return ans;
309+
}
78310
```
79311

80312
### **...**

0 commit comments

Comments
 (0)