Skip to content

Commit ff52610

Browse files
committedAug 28, 2022
feat: add solutions to lc problem: No.1632
No.1632.Rank Transform of a Matrix
1 parent 1ddf504 commit ff52610

File tree

5 files changed

+361
-2
lines changed

5 files changed

+361
-2
lines changed
 

Diff for: ‎solution/1600-1699/1632.Rank Transform of a Matrix/README.md

+127-1
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,148 @@ matrix[1][1] 的秩为 3 ,因为 matrix[1][1] > matrix[0][1], matrix[1][1] >
7474

7575
<!-- 这里可写通用的实现逻辑 -->
7676

77+
**方法一:贪心 + 并查集**
78+
79+
先考虑简化情形:没有相同的元素。那么显然最小的元素的秩为 $1$,第二小的元素则要考虑是否和最小元素同行或同列。于是得到贪心解法:从小到大遍历元素,并维护每行、每列的最大秩,该元素的秩即为同行、同列的最大秩加 $1$。见题目:[2371. Minimize Maximum Value in a Grid](/solution/2300-2399/2371.Minimize%20Maximum%20Value%20in%20a%20Grid/README.md)
80+
81+
存在相同元素时则较为复杂,假设两个相同元素同行(或同列),那么就要考虑到两个元素分别对应的行(或列)的最大秩。同时还可能出现联动,比如元素 `a``b` 同行,`b``c` 同列,那么要同时考虑这三个元素。
82+
83+
这种联动容易想到并查集,于是用并查集将相同元素分为几个连通块,对于每个连通块,里面所有元素对应的行或列的最大秩加 $1$,即为该连通块内所有元素的秩。
84+
7785
<!-- tabs:start -->
7886

7987
### **Python3**
8088

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

8391
```python
84-
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]
98+
99+
def union(a, b):
100+
p[find(a)] = find(b)
101+
102+
m, n = len(matrix), len(matrix[0])
103+
d = defaultdict(list)
104+
for i, row in enumerate(matrix):
105+
for j, v in enumerate(row):
106+
d[v].append((i, j))
107+
row_max = [0] * m
108+
col_max = [0] * n
109+
ans = [[0] * n for _ in range(m)]
110+
for v in sorted(d):
111+
p, rank = {}, defaultdict(int)
112+
for i, j in d[v]:
113+
union(i, j + 500)
114+
for i, j in d[v]:
115+
rank[find(i)] = max(rank[find(i)], row_max[i], col_max[j])
116+
for i, j in d[v]:
117+
ans[i][j] = row_max[i] = col_max[j] = 1 + rank[find(i)]
118+
return ans
85119
```
86120

87121
### **Java**
88122

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

91125
```java
126+
class Solution {
127+
private Map<Integer, Integer> p = new HashMap<>();
128+
private Map<Integer, Integer> rank = new HashMap<>();
129+
130+
public int[][] matrixRankTransform(int[][] matrix) {
131+
int m = matrix.length, n = matrix[0].length;
132+
TreeMap<Integer, List<int[]>> d = new TreeMap<>();
133+
for (int i = 0; i < m; ++i) {
134+
for (int j = 0; j < n; ++j) {
135+
d.computeIfAbsent(matrix[i][j], k -> new ArrayList<>()).add(new int[]{i, j});
136+
}
137+
}
138+
int[] rowMax = new int[m];
139+
int[] colMax = new int[n];
140+
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);
148+
}
149+
for (int[] x : g) {
150+
int i = x[0], j = x[1];
151+
rank.put(find(i), Math.max(rank.getOrDefault(find(i), 0), Math.max(rowMax[i], colMax[j])));
152+
}
153+
for (int[] x : g) {
154+
int i = x[0], j = x[1];
155+
ans[i][j] = 1 + rank.getOrDefault(find(i), 0);
156+
rowMax[i] = ans[i][j];
157+
colMax[j] = ans[i][j];
158+
}
159+
}
160+
return ans;
161+
}
162+
163+
private void union(int a, int b) {
164+
p.put(find(a), find(b));
165+
}
166+
167+
private int find(int x) {
168+
p.putIfAbsent(x, x);
169+
if (p.get(x) != x) {
170+
p.put(x, find(p.get(x)));
171+
}
172+
return p.get(x);
173+
}
174+
}
175+
```
92176

177+
### **C++**
178+
179+
```cpp
180+
class Solution {
181+
public:
182+
vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) {
183+
int m = matrix.size(), n = matrix[0].size();
184+
map<int, vector<pair<int, int>>> d;
185+
for (int i = 0; i < m; ++i) {
186+
for (int j = 0; j < n; ++j) {
187+
d[matrix[i][j]].push_back({i, j});
188+
}
189+
}
190+
vector<int> rowMax(m);
191+
vector<int> colMax(n);
192+
vector<vector<int>> ans(m, vector<int>(n));
193+
for (auto& [v, g] : d) {
194+
unordered_map<int, int> p;
195+
unordered_map<int, int> rank;
196+
for (auto [i, j] : g) {
197+
unite(i, j + 500, p);
198+
}
199+
for (auto [i, j] : g) {
200+
rank[find(i, p)] = max(rank[find(i, p)], max(rowMax[i], colMax[j]));
201+
}
202+
for (auto [i, j] : g) {
203+
ans[i][j] = rowMax[i] = colMax[j] = 1 + rank[find(i, p)];
204+
}
205+
}
206+
return ans;
207+
}
208+
209+
void unite(int a, int b, unordered_map<int, int>& p) {
210+
p[find(a, p)] = find(b, p);
211+
}
212+
213+
int find(int x, unordered_map<int, int>& p) {
214+
if (!p.count(x)) p[x] = x;
215+
if (p[x] != x) p[x] = find(p[x], p);
216+
return p[x];
217+
}
218+
};
93219
```
94220
95221
### **...**

Diff for: ‎solution/1600-1699/1632.Rank Transform of a Matrix/README_EN.md

+119-1
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,131 @@ The rank of matrix[1][1] is 3 because matrix[1][1] &gt; matrix[0][1], matrix[1][
6666
### **Python3**
6767

6868
```python
69-
69+
class Solution:
70+
def matrixRankTransform(self, matrix: List[List[int]]) -> List[List[int]]:
71+
def find(x):
72+
if p.setdefault(x, x) != x:
73+
p[x] = find(p[x])
74+
return p[x]
75+
76+
def union(a, b):
77+
p[find(a)] = find(b)
78+
79+
m, n = len(matrix), len(matrix[0])
80+
d = defaultdict(list)
81+
for i, row in enumerate(matrix):
82+
for j, v in enumerate(row):
83+
d[v].append((i, j))
84+
row_max = [0] * m
85+
col_max = [0] * n
86+
ans = [[0] * n for _ in range(m)]
87+
for v in sorted(d):
88+
p, rank = {}, defaultdict(int)
89+
for i, j in d[v]:
90+
union(i, j + 500)
91+
for i, j in d[v]:
92+
rank[find(i)] = max(rank[find(i)], row_max[i], col_max[j])
93+
for i, j in d[v]:
94+
ans[i][j] = row_max[i] = col_max[j] = 1 + rank[find(i)]
95+
return ans
7096
```
7197

7298
### **Java**
7399

74100
```java
101+
class Solution {
102+
private Map<Integer, Integer> p = new HashMap<>();
103+
private Map<Integer, Integer> rank = new HashMap<>();
104+
105+
public int[][] matrixRankTransform(int[][] matrix) {
106+
int m = matrix.length, n = matrix[0].length;
107+
TreeMap<Integer, List<int[]>> d = new TreeMap<>();
108+
for (int i = 0; i < m; ++i) {
109+
for (int j = 0; j < n; ++j) {
110+
d.computeIfAbsent(matrix[i][j], k -> new ArrayList<>()).add(new int[]{i, j});
111+
}
112+
}
113+
int[] rowMax = new int[m];
114+
int[] colMax = new int[n];
115+
int[][] ans = new int[m][n];
116+
for (var e : d.entrySet()) {
117+
int v = e.getKey();
118+
var g = e.getValue();
119+
p.clear();
120+
rank.clear();
121+
for (int[] x : g) {
122+
union(x[0], x[1] + 500);
123+
}
124+
for (int[] x : g) {
125+
int i = x[0], j = x[1];
126+
rank.put(find(i), Math.max(rank.getOrDefault(find(i), 0), Math.max(rowMax[i], colMax[j])));
127+
}
128+
for (int[] x : g) {
129+
int i = x[0], j = x[1];
130+
ans[i][j] = 1 + rank.getOrDefault(find(i), 0);
131+
rowMax[i] = ans[i][j];
132+
colMax[j] = ans[i][j];
133+
}
134+
}
135+
return ans;
136+
}
137+
138+
private void union(int a, int b) {
139+
p.put(find(a), find(b));
140+
}
141+
142+
private int find(int x) {
143+
p.putIfAbsent(x, x);
144+
if (p.get(x) != x) {
145+
p.put(x, find(p.get(x)));
146+
}
147+
return p.get(x);
148+
}
149+
}
150+
```
75151

152+
### **C++**
153+
154+
```cpp
155+
class Solution {
156+
public:
157+
vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) {
158+
int m = matrix.size(), n = matrix[0].size();
159+
map<int, vector<pair<int, int>>> d;
160+
for (int i = 0; i < m; ++i) {
161+
for (int j = 0; j < n; ++j) {
162+
d[matrix[i][j]].push_back({i, j});
163+
}
164+
}
165+
vector<int> rowMax(m);
166+
vector<int> colMax(n);
167+
vector<vector<int>> ans(m, vector<int>(n));
168+
for (auto& [v, g] : d) {
169+
unordered_map<int, int> p;
170+
unordered_map<int, int> rank;
171+
for (auto [i, j] : g) {
172+
unite(i, j + 500, p);
173+
}
174+
for (auto [i, j] : g) {
175+
rank[find(i, p)] = max(rank[find(i, p)], max(rowMax[i], colMax[j]));
176+
}
177+
for (auto [i, j] : g) {
178+
ans[i][j] = rowMax[i] = colMax[j] = 1 + rank[find(i, p)];
179+
}
180+
}
181+
return ans;
182+
}
183+
184+
void unite(int a, int b, unordered_map<int, int>& p) {
185+
p[find(a, p)] = find(b, p);
186+
}
187+
188+
int find(int x, unordered_map<int, int>& p) {
189+
if (!p.count(x)) p[x] = x;
190+
if (p[x] != x) p[x] = find(p[x], p);
191+
return p[x];
192+
}
193+
};
76194
```
77195
78196
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
vector<vector<int>> matrixRankTransform(vector<vector<int>>& matrix) {
4+
int m = matrix.size(), n = matrix[0].size();
5+
map<int, vector<pair<int, int>>> d;
6+
for (int i = 0; i < m; ++i) {
7+
for (int j = 0; j < n; ++j) {
8+
d[matrix[i][j]].push_back({i, j});
9+
}
10+
}
11+
vector<int> rowMax(m);
12+
vector<int> colMax(n);
13+
vector<vector<int>> ans(m, vector<int>(n));
14+
for (auto& [v, g] : d) {
15+
unordered_map<int, int> p;
16+
unordered_map<int, int> rank;
17+
for (auto [i, j] : g) {
18+
unite(i, j + 500, p);
19+
}
20+
for (auto [i, j] : g) {
21+
rank[find(i, p)] = max(rank[find(i, p)], max(rowMax[i], colMax[j]));
22+
}
23+
for (auto [i, j] : g) {
24+
ans[i][j] = rowMax[i] = colMax[j] = 1 + rank[find(i, p)];
25+
}
26+
}
27+
return ans;
28+
}
29+
30+
void unite(int a, int b, unordered_map<int, int>& p) {
31+
p[find(a, p)] = find(b, p);
32+
}
33+
34+
int find(int x, unordered_map<int, int>& p) {
35+
if (!p.count(x)) p[x] = x;
36+
if (p[x] != x) p[x] = find(p[x], p);
37+
return p[x];
38+
}
39+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
class Solution {
2+
private Map<Integer, Integer> p = new HashMap<>();
3+
private Map<Integer, Integer> rank = new HashMap<>();
4+
5+
public int[][] matrixRankTransform(int[][] matrix) {
6+
int m = matrix.length, n = matrix[0].length;
7+
TreeMap<Integer, List<int[]>> d = new TreeMap<>();
8+
for (int i = 0; i < m; ++i) {
9+
for (int j = 0; j < n; ++j) {
10+
d.computeIfAbsent(matrix[i][j], k -> new ArrayList<>()).add(new int[]{i, j});
11+
}
12+
}
13+
int[] rowMax = new int[m];
14+
int[] colMax = new int[n];
15+
int[][] ans = new int[m][n];
16+
for (var e : d.entrySet()) {
17+
int v = e.getKey();
18+
var g = e.getValue();
19+
p.clear();
20+
rank.clear();
21+
for (int[] x : g) {
22+
union(x[0], x[1] + 500);
23+
}
24+
for (int[] x : g) {
25+
int i = x[0], j = x[1];
26+
rank.put(find(i), Math.max(rank.getOrDefault(find(i), 0), Math.max(rowMax[i], colMax[j])));
27+
}
28+
for (int[] x : g) {
29+
int i = x[0], j = x[1];
30+
ans[i][j] = 1 + rank.getOrDefault(find(i), 0);
31+
rowMax[i] = ans[i][j];
32+
colMax[j] = ans[i][j];
33+
}
34+
}
35+
return ans;
36+
}
37+
38+
private void union(int a, int b) {
39+
p.put(find(a), find(b));
40+
}
41+
42+
private int find(int x) {
43+
p.putIfAbsent(x, x);
44+
if (p.get(x) != x) {
45+
p.put(x, find(p.get(x)));
46+
}
47+
return p.get(x);
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution:
2+
def matrixRankTransform(self, matrix: List[List[int]]) -> List[List[int]]:
3+
def find(x):
4+
if p.setdefault(x, x) != x:
5+
p[x] = find(p[x])
6+
return p[x]
7+
8+
def union(a, b):
9+
p[find(a)] = find(b)
10+
11+
m, n = len(matrix), len(matrix[0])
12+
d = defaultdict(list)
13+
for i, row in enumerate(matrix):
14+
for j, v in enumerate(row):
15+
d[v].append((i, j))
16+
row_max = [0] * m
17+
col_max = [0] * n
18+
ans = [[0] * n for _ in range(m)]
19+
for v in sorted(d):
20+
p, rank = {}, defaultdict(int)
21+
for i, j in d[v]:
22+
union(i, j + 500)
23+
for i, j in d[v]:
24+
rank[find(i)] = max(rank[find(i)], row_max[i], col_max[j])
25+
for i, j in d[v]:
26+
ans[i][j] = row_max[i] = col_max[j] = 1 + rank[find(i)]
27+
return ans

0 commit comments

Comments
 (0)
Please sign in to comment.