Skip to content

Commit 55b1087

Browse files
committed
feat: add solutions to lc problem: No.1632
No.1632.Rank Transform of a Matrix
1 parent 75c134b commit 55b1087

File tree

6 files changed

+587
-176
lines changed

6 files changed

+587
-176
lines changed

solution/1600-1699/1632.Rank Transform of a Matrix/README.md

+198-58
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,38 @@ matrix[1][1] 的秩为 3 ,因为 matrix[1][1] > matrix[0][1], matrix[1][1] >
8282

8383
这种联动容易想到并查集,于是用并查集将相同元素分为几个连通块,对于每个连通块,里面所有元素对应的行或列的最大秩加 $1$,即为该连通块内所有元素的秩。
8484

85+
时间复杂度 $O(m \times n \times \log(m \times n))$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数。
86+
8587
<!-- tabs:start -->
8688

8789
### **Python3**
8890

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

9193
```python
92-
class Solution:
93-
def matrixRankTransform(self, matrix: List[List[int]]) -> List[List[int]]:
94-
def find(x):
95-
if p.setdefault(x, x) != x:
96-
p[x] = find(p[x])
97-
return p[x]
94+
class UnionFind:
95+
def __init__(self, n):
96+
self.p = list(range(n))
97+
self.size = [1] * n
98+
99+
def find(self, x):
100+
if self.p[x] != x:
101+
self.p[x] = self.find(self.p[x])
102+
return self.p[x]
103+
104+
def union(self, a, b):
105+
pa, pb = self.find(a), self.find(b)
106+
if pa != pb:
107+
if self.size[pa] > self.size[pb]:
108+
self.p[pb] = pa
109+
self.size[pa] += self.size[pb]
110+
else:
111+
self.p[pa] = pb
112+
self.size[pb] += self.size[pa]
98113

99-
def union(a, b):
100-
p[find(a)] = find(b)
101114

115+
class Solution:
116+
def matrixRankTransform(self, matrix: List[List[int]]) -> List[List[int]]:
102117
m, n = len(matrix), len(matrix[0])
103118
d = defaultdict(list)
104119
for i, row in enumerate(matrix):
@@ -108,13 +123,14 @@ class Solution:
108123
col_max = [0] * n
109124
ans = [[0] * n for _ in range(m)]
110125
for v in sorted(d):
111-
p, rank = {}, defaultdict(int)
126+
uf = UnionFind(m + n)
127+
rank = defaultdict(int)
112128
for i, j in d[v]:
113-
union(i, j + 500)
129+
uf.union(i, j + m)
114130
for i, j in d[v]:
115-
rank[find(i)] = max(rank[find(i)], row_max[i], col_max[j])
131+
rank[uf.find(i)] = max(rank[uf.find(i)], row_max[i], col_max[j])
116132
for i, j in d[v]:
117-
ans[i][j] = row_max[i] = col_max[j] = 1 + rank[find(i)]
133+
ans[i][j] = row_max[i] = col_max[j] = 1 + rank[uf.find(i)]
118134
return ans
119135
```
120136

@@ -123,10 +139,42 @@ class Solution:
123139
<!-- 这里可写当前语言的特殊实现逻辑 -->
124140

125141
```java
126-
class Solution {
127-
private Map<Integer, Integer> p = new HashMap<>();
128-
private Map<Integer, Integer> rank = new HashMap<>();
142+
class UnionFind {
143+
private int[] p;
144+
private int[] size;
145+
146+
public UnionFind(int n) {
147+
p = new int[n];
148+
size = new int[n];
149+
for (int i = 0; i < n; ++i) {
150+
p[i] = i;
151+
size[i] = 1;
152+
}
153+
}
154+
155+
public int find(int x) {
156+
if (p[x] != x) {
157+
p[x] = find(p[x]);
158+
}
159+
return p[x];
160+
}
161+
162+
public void union(int a, int b) {
163+
int pa = find(a), pb = find(b);
164+
if (pa != pb) {
165+
if (size[pa] > size[pb]) {
166+
p[pb] = pa;
167+
size[pa] += size[pb];
168+
} else {
169+
p[pa] = pb;
170+
size[pb] += size[pa];
171+
}
172+
}
173+
}
174+
}
129175

176+
177+
class Solution {
130178
public int[][] matrixRankTransform(int[][] matrix) {
131179
int m = matrix.length, n = matrix[0].length;
132180
TreeMap<Integer, List<int[]>> d = new TreeMap<>();
@@ -138,46 +186,63 @@ class Solution {
138186
int[] rowMax = new int[m];
139187
int[] colMax = new int[n];
140188
int[][] ans = new int[m][n];
141-
for (var e : d.entrySet()) {
142-
int v = e.getKey();
143-
var g = e.getValue();
144-
p.clear();
145-
rank.clear();
146-
for (int[] x : g) {
147-
union(x[0], x[1] + 500);
189+
for (var ps : d.values()) {
190+
UnionFind uf = new UnionFind(m + n);
191+
int[] rank = new int[m + n];
192+
for (var p : ps) {
193+
uf.union(p[0], p[1] + m);
148194
}
149-
for (int[] x : g) {
150-
int i = x[0], j = x[1];
151-
rank.put(find(i),
152-
Math.max(rank.getOrDefault(find(i), 0), Math.max(rowMax[i], colMax[j])));
195+
for (var p : ps) {
196+
int i = p[0], j = p[1];
197+
rank[uf.find(i)] = Math.max(rank[uf.find(i)], Math.max(rowMax[i], colMax[j]));
153198
}
154-
for (int[] x : g) {
155-
int i = x[0], j = x[1];
156-
ans[i][j] = 1 + rank.getOrDefault(find(i), 0);
199+
for (var p : ps) {
200+
int i = p[0], j = p[1];
201+
ans[i][j] = 1 + rank[uf.find(i)];
157202
rowMax[i] = ans[i][j];
158203
colMax[j] = ans[i][j];
159204
}
160205
}
161206
return ans;
162207
}
208+
}
209+
```
210+
211+
### **C++**
212+
213+
```cpp
214+
class UnionFind {
215+
public:
216+
UnionFind(int n) {
217+
p = vector<int>(n);
218+
size = vector<int>(n, 1);
219+
iota(p.begin(), p.end(), 0);
220+
}
163221

164-
private void union(int a, int b) {
165-
p.put(find(a), find(b));
222+
void unite(int a, int b) {
223+
int pa = find(a), pb = find(b);
224+
if (pa != pb) {
225+
if (size[pa] > size[pb]) {
226+
p[pb] = pa;
227+
size[pa] += size[pb];
228+
} else {
229+
p[pa] = pb;
230+
size[pb] += size[pa];
231+
}
232+
}
166233
}
167234

168-
private int find(int x) {
169-
p.putIfAbsent(x, x);
170-
if (p.get(x) != x) {
171-
p.put(x, find(p.get(x)));
235+
int find(int x) {
236+
if (p[x] != x) {
237+
p[x] = find(p[x]);
172238
}
173-
return p.get(x);
239+
return p[x];
174240
}
175-
}
176-
```
177241

178-
### **C++**
242+
private:
243+
vector<int> p, size;
244+
};
179245

180-
```cpp
181246
class Solution {
182247
public:
183248
vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) {
@@ -191,32 +256,107 @@ public:
191256
vector<int> rowMax(m);
192257
vector<int> colMax(n);
193258
vector<vector<int>> ans(m, vector<int>(n));
194-
for (auto& [v, g] : d) {
195-
unordered_map<int, int> p;
196-
unordered_map<int, int> rank;
197-
for (auto [i, j] : g) {
198-
unite(i, j + 500, p);
259+
for (auto& [_, ps] : d) {
260+
UnionFind uf(m + n);
261+
vector<int> rank(m + n);
262+
for (auto& [i, j] : ps) {
263+
uf.unite(i, j + m);
199264
}
200-
for (auto [i, j] : g) {
201-
rank[find(i, p)] = max(rank[find(i, p)], max(rowMax[i], colMax[j]));
265+
for (auto& [i, j] : ps) {
266+
rank[uf.find(i)] = max({rank[uf.find(i)], rowMax[i], colMax[j]});
202267
}
203-
for (auto [i, j] : g) {
204-
ans[i][j] = rowMax[i] = colMax[j] = 1 + rank[find(i, p)];
268+
for (auto& [i, j] : ps) {
269+
ans[i][j] = rowMax[i] = colMax[j] = 1 + rank[uf.find(i)];
205270
}
206271
}
207272
return ans;
208273
}
274+
};
275+
```
209276
210-
void unite(int a, int b, unordered_map<int, int>& p) {
211-
p[find(a, p)] = find(b, p);
212-
}
277+
### **Go**
213278
214-
int find(int x, unordered_map<int, int>& p) {
215-
if (!p.count(x)) p[x] = x;
216-
if (p[x] != x) p[x] = find(p[x], p);
217-
return p[x];
218-
}
219-
};
279+
```go
280+
type unionFind struct {
281+
p, size []int
282+
}
283+
284+
func newUnionFind(n int) *unionFind {
285+
p := make([]int, n)
286+
size := make([]int, n)
287+
for i := range p {
288+
p[i] = i
289+
size[i] = 1
290+
}
291+
return &unionFind{p, size}
292+
}
293+
294+
func (uf *unionFind) find(x int) int {
295+
if uf.p[x] != x {
296+
uf.p[x] = uf.find(uf.p[x])
297+
}
298+
return uf.p[x]
299+
}
300+
301+
func (uf *unionFind) union(a, b int) {
302+
pa, pb := uf.find(a), uf.find(b)
303+
if pa != pb {
304+
if uf.size[pa] > uf.size[pb] {
305+
uf.p[pb] = pa
306+
uf.size[pa] += uf.size[pb]
307+
} else {
308+
uf.p[pa] = pb
309+
uf.size[pb] += uf.size[pa]
310+
}
311+
}
312+
}
313+
314+
func matrixRankTransform(matrix [][]int) [][]int {
315+
m, n := len(matrix), len(matrix[0])
316+
type pair struct{ i, j int }
317+
d := map[int][]pair{}
318+
for i, row := range matrix {
319+
for j, v := range row {
320+
d[v] = append(d[v], pair{i, j})
321+
}
322+
}
323+
rowMax := make([]int, m)
324+
colMax := make([]int, n)
325+
ans := make([][]int, m)
326+
for i := range ans {
327+
ans[i] = make([]int, n)
328+
}
329+
vs := []int{}
330+
for v := range d {
331+
vs = append(vs, v)
332+
}
333+
sort.Ints(vs)
334+
for _, v := range vs {
335+
ps := d[v]
336+
uf := newUnionFind(m + n)
337+
rank := make([]int, m+n)
338+
for _, p := range ps {
339+
uf.union(p.i, p.j+m)
340+
}
341+
for _, p := range ps {
342+
i, j := p.i, p.j
343+
rank[uf.find(i)] = max(rank[uf.find(i)], max(rowMax[i], colMax[j]))
344+
}
345+
for _, p := range ps {
346+
i, j := p.i, p.j
347+
ans[i][j] = 1 + rank[uf.find(i)]
348+
rowMax[i], colMax[j] = ans[i][j], ans[i][j]
349+
}
350+
}
351+
return ans
352+
}
353+
354+
func max(a, b int) int {
355+
if a > b {
356+
return a
357+
}
358+
return b
359+
}
220360
```
221361

222362
### **...**

0 commit comments

Comments
 (0)