Skip to content

Commit da71f89

Browse files
committed
Add solution #1632
1 parent 5e6a219 commit da71f89

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# 1,436 LeetCode solutions in JavaScript
1+
# 1,437 LeetCode solutions in JavaScript
22

33
[https://leetcodejavascript.com](https://leetcodejavascript.com)
44

@@ -1259,6 +1259,7 @@
12591259
1629|[Slowest Key](./solutions/1629-slowest-key.js)|Easy|
12601260
1630|[Arithmetic Subarrays](./solutions/1630-arithmetic-subarrays.js)|Medium|
12611261
1631|[Path With Minimum Effort](./solutions/1631-path-with-minimum-effort.js)|Medium|
1262+
1632|[Rank Transform of a Matrix](./solutions/1632-rank-transform-of-a-matrix.js)|Hard|
12621263
1657|[Determine if Two Strings Are Close](./solutions/1657-determine-if-two-strings-are-close.js)|Medium|
12631264
1668|[Maximum Repeating Substring](./solutions/1668-maximum-repeating-substring.js)|Easy|
12641265
1669|[Merge In Between Linked Lists](./solutions/1669-merge-in-between-linked-lists.js)|Medium|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/**
2+
* 1632. Rank Transform of a Matrix
3+
* https://leetcode.com/problems/rank-transform-of-a-matrix/
4+
* Difficulty: Hard
5+
*
6+
* Given an m x n matrix, return a new matrix answer where answer[row][col] is the rank of
7+
* matrix[row][col].
8+
*
9+
* The rank is an integer that represents how large an element is compared to other elements.
10+
* It is calculated using the following rules:
11+
* - The rank is an integer starting from 1.
12+
* - If two elements p and q are in the same row or column, then:
13+
* - If p < q then rank(p) < rank(q)
14+
* - If p == q then rank(p) == rank(q)
15+
* - If p > q then rank(p) > rank(q)
16+
* - The rank should be as small as possible.
17+
*
18+
* The test cases are generated so that answer is unique under the given rules.
19+
*/
20+
21+
/**
22+
* @param {number[][]} matrix
23+
* @return {number[][]}
24+
*/
25+
var matrixRankTransform = function(matrix) {
26+
const rows = matrix.length;
27+
const cols = matrix[0].length;
28+
const result = Array.from({ length: rows }, () => new Array(cols).fill(0));
29+
const parent = new Array(rows * cols).fill(-1);
30+
const elements = [];
31+
32+
for (let row = 0; row < rows; row++) {
33+
const valueToCoords = new Map();
34+
for (let col = 0; col < cols; col++) {
35+
const value = matrix[row][col];
36+
if (!valueToCoords.has(value)) valueToCoords.set(value, []);
37+
valueToCoords.get(value).push([row, col]);
38+
}
39+
for (const coords of valueToCoords.values()) {
40+
for (let i = 1; i < coords.length; i++) {
41+
const [r1, c1] = coords[0];
42+
const [r2, c2] = coords[i];
43+
union(r1 * cols + c1, r2 * cols + c2);
44+
}
45+
}
46+
}
47+
48+
for (let col = 0; col < cols; col++) {
49+
const valueToCoords = new Map();
50+
for (let row = 0; row < rows; row++) {
51+
const value = matrix[row][col];
52+
if (!valueToCoords.has(value)) valueToCoords.set(value, []);
53+
valueToCoords.get(value).push([row, col]);
54+
}
55+
for (const coords of valueToCoords.values()) {
56+
for (let i = 1; i < coords.length; i++) {
57+
const [r1, c1] = coords[0];
58+
const [r2, c2] = coords[i];
59+
union(r1 * cols + c1, r2 * cols + c2);
60+
}
61+
}
62+
}
63+
64+
for (let row = 0; row < rows; row++) {
65+
for (let col = 0; col < cols; col++) {
66+
elements.push([matrix[row][col], row, col]);
67+
}
68+
}
69+
elements.sort((a, b) => a[0] - b[0]);
70+
71+
const rowMaxRank = new Array(rows).fill(0);
72+
const colMaxRank = new Array(cols).fill(0);
73+
const groups = new Map();
74+
75+
for (let i = 0; i < elements.length; i++) {
76+
const [value, row, col] = elements[i];
77+
const root = find(row * cols + col);
78+
if (!groups.has(root)) groups.set(root, []);
79+
groups.get(root).push([row, col]);
80+
}
81+
82+
let i = 0;
83+
while (i < elements.length) {
84+
const value = elements[i][0];
85+
const currentGroups = new Map();
86+
while (i < elements.length && elements[i][0] === value) {
87+
const [, row, col] = elements[i];
88+
const root = find(row * cols + col);
89+
if (!currentGroups.has(root)) currentGroups.set(root, []);
90+
currentGroups.get(root).push([row, col]);
91+
i++;
92+
}
93+
94+
for (const [root, coords] of currentGroups) {
95+
let maxRank = 0;
96+
for (const [row, col] of coords) {
97+
maxRank = Math.max(maxRank, rowMaxRank[row], colMaxRank[col]);
98+
}
99+
const rank = maxRank + 1;
100+
for (const [row, col] of coords) {
101+
result[row][col] = rank;
102+
rowMaxRank[row] = rank;
103+
colMaxRank[col] = rank;
104+
}
105+
}
106+
}
107+
108+
return result;
109+
110+
function find(x) {
111+
if (parent[x] < 0) return x;
112+
return parent[x] = find(parent[x]);
113+
}
114+
115+
function union(x, y) {
116+
const px = find(x);
117+
const py = find(y);
118+
119+
if (px !== py) {
120+
if (parent[px] < parent[py]) {
121+
parent[px] += parent[py];
122+
parent[py] = px;
123+
} else {
124+
parent[py] += parent[px];
125+
parent[px] = py;
126+
}
127+
}
128+
}
129+
};

0 commit comments

Comments
 (0)