Skip to content

Commit 9f2b97d

Browse files
committed
❌ [947]
1 parent a2c3848 commit 9f2b97d

File tree

6 files changed

+201
-5
lines changed

6 files changed

+201
-5
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.DS_Store
2+
es.log

947/my_solution.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
class UnionFind {
2+
constructor() {
3+
this.parent = new Map();
4+
this.rank = new Map();
5+
}
6+
7+
find(x) {
8+
if (this.parent.get(x) !== x) {
9+
this.parent.set(x, this.find(this.parent.get(x))); // Path compression
10+
}
11+
return this.parent.get(x);
12+
}
13+
14+
union(x, y) {
15+
let rootX = this.find(x);
16+
let rootY = this.find(y);
17+
if (rootX !== rootY) {
18+
let rankX = this.rank.get(rootX) || 1;
19+
let rankY = this.rank.get(rootY) || 1;
20+
21+
if (rankX > rankY) {
22+
this.parent.set(rootY, rootX);
23+
} else if (rankX < rankY) {
24+
this.parent.set(rootX, rootY);
25+
} else {
26+
this.parent.set(rootY, rootX);
27+
this.rank.set(rootX, rankX + 1);
28+
}
29+
}
30+
}
31+
32+
add(x) {
33+
if (!this.parent.has(x)) {
34+
this.parent.set(x, x);
35+
this.rank.set(x, 1);
36+
}
37+
}
38+
}
39+
40+
/**
41+
* @param {number[][]} stones
42+
* @return {number}
43+
*/
44+
var removeStones = function (stones) {
45+
const uf = new UnionFind();
46+
// console.log("uf", uf);
47+
48+
// Use separate identifiers for rows and columns by adding a large constant to column identifiers
49+
for (let [xs, ys] of stones) {
50+
uf.add(xs); // Add row identifier
51+
uf.add(ys + 10001); // Add column identifier, shifted to avoid collision with row IDs
52+
uf.union(xs, ys + 10001); // Union row and column
53+
console.log("each loop\n",uf);
54+
}
55+
console.log("post loop\n",uf);
56+
57+
const uniqueParents = new Set();
58+
for (let [xs, ys] of stones) {
59+
uniqueParents.add(uf.find(xs));
60+
}
61+
62+
return stones.length - uniqueParents.size;
63+
};
64+
65+
66+
// Test Case 1: Simple connected component
67+
let stones1 = [[0, 0], [0, 1], [1, 0], [1, 2], [2, 1], [2, 2]];
68+
console.log(removeStones(stones1)); // Expected output: 5
69+
70+
// // Test Case 2: No stones
71+
// let stones2 = [];
72+
// console.log(removeStones(stones2)); // Expected output: 0
73+
//
74+
// // Test Case 3: Single stone
75+
// let stones3 = [[0, 0]];
76+
// console.log(removeStones(stones3)); // Expected output: 0
77+
//
78+
// // Test Case 4: Two disconnected stones
79+
// let stones4 = [[0, 0], [1, 1]];
80+
// console.log(removeStones(stones4)); // Expected output: 0
81+
//
82+
// // Test Case 5: Multiple stones forming a complex structure
83+
// let stones5 = [[0, 0], [0, 2], [1, 1], [2, 0], [2, 2]];
84+
// console.log(removeStones(stones5)); // Expected output: 3

947/solution.js

Whitespace-only changes.

947/union_find.js

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
class UnionFind {
2+
constructor() {
3+
this.parent = new Map();
4+
this.rank = new Map();
5+
console.log("Initial parent map:", JSON.stringify([...this.parent]));
6+
console.log("Initial rank map:", JSON.stringify([...this.rank]));
7+
}
8+
9+
add(x) {
10+
if (this.parent.has(x)) return;
11+
12+
this.parent.set(x, x);
13+
this.rank.set(x, 1);
14+
}
15+
16+
find(x) {
17+
console.log(`~~> Find(${x})`);
18+
19+
// Find the root of the element x
20+
if (this.parent.get(x) !== x) {
21+
console.log(`Path compression for element ${x}`);
22+
this.parent.set(x, this.find(this.parent.get(x))); // Path compression
23+
}
24+
25+
console.log(`Find(${x}) -> Root is ${this.parent.get(x)}`);
26+
return this.parent.get(x);
27+
}
28+
29+
union(x, y) {
30+
console.log(`\nUnion(${x}, ${y})`);
31+
32+
this.add(x);
33+
this.add(y);
34+
35+
// Find the roots of x and y
36+
console.log(`~> before find:`, JSON.stringify([...this.parent]));
37+
let rootX = this.find(x);
38+
let rootY = this.find(y);
39+
40+
if (rootX !== rootY) {
41+
console.log(`Union(${x}, ${y}) -> Already in the same set`);
42+
return;
43+
}
44+
45+
let rankX = this.rank.get(rootX);
46+
let rankY = this.rank.get(rootY);
47+
48+
console.log(`rootX: ${rootX}, \nrootY: ${rootY}, \nrankX: ${rankX}, \nrankY: ${rankY}`);
49+
console.log(`~~~> after find:`, JSON.stringify([...this.parent]));
50+
51+
// If they have different roots, perform union
52+
if (rankX > rankY) {
53+
console.log(`(x <- y) -> Root of ${y} (root ${rootY}) attached to root ${rootX}`);
54+
this.parent.set(rootY, rootX);
55+
} else if (rankX < rankY) {
56+
console.log(`(x -> y) -> Root of ${x} (root ${rootX}) attached to root ${rootY}`);
57+
this.parent.set(rootX, rootY);
58+
} else {
59+
console.log(`(x <- y) -> Roots are equal, root ${rootY} attached to root ${rootX}`);
60+
this.parent.set(rootY, rootX);
61+
this.rank.set(rootX, rankX + 1); // ONLY increase the rank of the new root
62+
}
63+
64+
console.log(`parent: ${JSON.stringify([...this.parent])}`);
65+
console.log(`rank: ${JSON.stringify([...this.rank])}`);
66+
}
67+
}
68+
69+
// Create an instance of UnionFind with 8 elements (0 through 7)
70+
let uf = new UnionFind();
71+
72+
// Test Cases
73+
console.log("\nTest Case 1: Union operations");
74+
// uf.union(1, 2);
75+
// uf.union(2, 3);
76+
77+
uf.union(0, 0);
78+
uf.union(0, 1);
79+
uf.union(1, 0);
80+
uf.union(1, 2);
81+
uf.union(2, 1);
82+
uf.union(2, 2);
83+
84+
// uf.union(4, 5);
85+
// uf.union(6, 7);
86+
// uf.union(5, 6);
87+
// uf.union(3, 7); // This will connect two previously separate sets
88+
// // console.log("\n--> size", uf.size());
89+
//
90+
// console.log("\nTest Case 2: Find operations");
91+
// console.log("\n- Find(1):", uf.find(1)); // Should compress path for 1 -> 2 -> 3 -> root
92+
// console.log("\n- Find(2):", uf.find(2)); // Already compressed
93+
// console.log("\n- Find(5):", uf.find(5)); // Should show the root of the 4-5-6-7 component
94+
// console.log("Find(8):", uf.find(8)); // 8 should be its own root (no connections yet)
95+
//
96+
// console.log("\nTest Case 3: Additional Unions and Finds");
97+
// uf.union(8, 9);
98+
// console.log("Find(9):", uf.find(9)); // Should point to root after union with 8
99+
// uf.union(3, 8); // This will connect the 1-2-3-7-6-5-4 set with 8-9
100+
// console.log("Find(9):", uf.find(9)); // Should now point to the root of the entire connected set
101+
// console.log("Final parent array:", uf.parent);
102+
// console.log("Final rank array:", uf.rank);

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ Batch create:
174174
<!--
175175
NOTE: JS IS HERE
176176
-->
177-
```ssh
178-
chapter=743 && mkdir ./$chapter && touch ./$chapter/my_solution.js && touch ./$chapter/solution.js && alias x="node ./$chapter/my_solution.js"
177+
```sh
178+
chapter=947 && mkdir ./$chapter && touch ./$chapter/my_solution.js && touch ./$chapter/solution.js && alias x="node ./$chapter/my_solution.js"
179179
```
180180
> then you can use `x` for quick debug.
181181

test.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,16 @@
119119
// console.log(Array(26).fill(0));
120120

121121

122-
let x = [1, 2, 3]
122+
// let x = [1, 2, 3]
123+
// console.log(x)
124+
// console.log("splicing index 1 from x")
125+
// x.splice(1, 1)
126+
// console.log(x)
127+
128+
let x = 1;
129+
console.log("x")
123130
console.log(x)
124-
console.log("splicing index 1 from x")
125-
x.splice(1, 1)
131+
132+
x = [1, 2, 3];
133+
console.log("> x")
126134
console.log(x)

0 commit comments

Comments
 (0)