Skip to content

Commit c06e63f

Browse files
solves #1168: optimize water distribution in village
1 parent 3b8abbc commit c06e63f

File tree

3 files changed

+83
-126
lines changed

3 files changed

+83
-126
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@
514514
| 1154 | [Day of The Year](https://leetcode.com/problems/day-of-the-year) | [![Java](assets/java.png)](src/DayOfTheYear.java) | |
515515
| 1160 | [Find Words That Can Be Formed By Characters](https://leetcode.com/problems/find-words-that-can-be-formed-by-characters) | | |
516516
| 1165 | [Single Row Keyboard](https://leetcode.com/problems/single-row-keyboard) | [![Java](assets/java.png)](src/FindWordsThatCanBeFormedByCharacters.java) | |
517+
| 1168 | [Optimize Water Distribution in a Village](https://leetcode.com/problems/optimize-water-distribution-in-a-village) | [![Java](assets/java.png)](src/OptimizeWaterDistributionInAVillage.java) | |
517518
| 1170 | [Compare Strings By Frequency of the Smallest Character](https://leetcode.com/problems/compare-strings-by-frequency-of-the-smallest-character) | | |
518519
| 1175 | [Prime Arrangements](https://leetcode.com/problems/prime-arrangements) | [![Java](assets/java.png)](src/PrimeArrangements.java) | |
519520
| 1176 | 🔒 [Diet Plan Performance](https://leetcode.com/problems/diet-plan-performance) | | |

Diff for: src/HelloWorld.java

+1-126
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,2 @@
1-
import java.util.ArrayList;
2-
import java.util.Arrays;
3-
import java.util.HashMap;
4-
import java.util.HashSet;
5-
import java.util.LinkedList;
6-
import java.util.List;
7-
import java.util.Map;
8-
import java.util.Queue;
9-
import java.util.Set;
10-
11-
/*
12-
kahns algorithm
13-
t: O(V + E)
14-
S: O(E)
15-
*/
16-
171
public class HelloWorld {
18-
private static class QuickUnionFind {
19-
private final int[] array;
20-
21-
public QuickUnionFind(int size) {
22-
array = new int[size];
23-
for (int i = 0 ; i < array.length ; i++) {
24-
array[i] = i;
25-
}
26-
}
27-
28-
public void union(int x, int y) {
29-
final int rootX = find(x), rootY = find(y);
30-
if (rootY == rootX) {
31-
return;
32-
}
33-
34-
for (int i = 0 ; i < array.length ; i++) {
35-
if (array[i] == rootY) {
36-
array[i] = rootX;
37-
}
38-
}
39-
}
40-
41-
public int find(int num) {
42-
return array[num];
43-
}
44-
45-
public boolean areConnected(int x, int y) {
46-
return find(x) == find(y);
47-
}
48-
}
49-
50-
private static final class QuickUnionDisjointSet {
51-
private final int[] array;
52-
53-
public QuickUnionDisjointSet(int size) {
54-
array = new int[size];
55-
for (int i = 0 ; i < array.length ; i++) {
56-
array[i] = i;
57-
}
58-
}
59-
60-
public int find(int num) {
61-
while (array[num] != num) {
62-
num = array[num];
63-
}
64-
return num;
65-
}
66-
67-
public boolean areConnected(int x, int y) {
68-
return find(x) == find(y);
69-
}
70-
71-
public void union(int x, int y) {
72-
final int rootX = find(x), rootY = find(y);
73-
if (rootX == rootY) {
74-
return;
75-
}
76-
array[rootY] = rootX;
77-
}
78-
}
79-
80-
private static final class DisjointSetRank {
81-
private final int[] array;
82-
private final int[] rank;
83-
84-
public DisjointSetRank(int size) {
85-
array = new int[size];
86-
rank = new int[size];
87-
for (int i = 0 ; i < array.length ; i++) {
88-
rank[i] = 1;
89-
array[i] = i;
90-
}
91-
}
92-
93-
// T: O(logN)
94-
// S: O(1)
95-
public int find(int num) {
96-
if (num == array[num]) {
97-
return num;
98-
}
99-
final int root = find(array[num]);
100-
array[num] = root;
101-
return root;
102-
}
103-
104-
// T: O(logN)
105-
// S: O(1)
106-
public void union(int x, int y) {
107-
final int rootX = find(x), rootY = find(y);
108-
if (rootX == rootY) {
109-
return;
110-
}
111-
if (rank[rootX] > rank[rootY]) {
112-
array[rootY] = rootX;
113-
} else if (rank[rootX] < rank[rootY]) {
114-
array[rootX] = rootY;
115-
} else {
116-
array[rootY] = rootX;
117-
rank[rootX]++;
118-
}
119-
}
120-
121-
// T: O(logN)
122-
// S: O(1)
123-
public boolean areConnected(int x, int y) {
124-
return find(x) == find(y);
125-
}
126-
}
127-
}
2+
}

Diff for: src/OptimizeWaterDistributionInAVillage.java

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// https://leetcode.com/problems/optimize-water-distribution-in-a-village
2+
// N = n, E = |pipes|
3+
// T: O(N + (N + E) log(N + E) + E al(N)) = O((N + E) log(N + E)) al = inverse Ackermann function
4+
// S: O(N + E)
5+
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
import java.util.Comparator;
9+
import java.util.List;
10+
11+
public class OptimizeWaterDistributionInAVillage {
12+
private static final class DisjointSet {
13+
private final int[] roots, rank;
14+
15+
public DisjointSet(int size) {
16+
roots = new int[size];
17+
rank = new int[size];
18+
for (int i = 0 ; i < size ; i++) {
19+
roots[i] = i;
20+
rank[i] = 1;
21+
}
22+
}
23+
24+
public int find(int num) {
25+
if (num == roots[num]) {
26+
return num;
27+
}
28+
return roots[num] = find(roots[num]);
29+
}
30+
31+
public boolean isConnected(int x, int y) {
32+
return find(x) == find(y);
33+
}
34+
35+
public void union(int x, int y) {
36+
final int rootX = find(x), rootY = find(y);
37+
if (rootX == rootY) {
38+
return;
39+
}
40+
if (rank[rootX] > rank[rootY]) {
41+
roots[rootY] = rootX;
42+
} else if (rank[rootX] < rank[rootY]) {
43+
roots[rootX] = rootY;
44+
} else {
45+
roots[rootY] = rootX;
46+
rank[rootX]++;
47+
}
48+
}
49+
}
50+
51+
// Kruskal's algorithm to find MST in unordered weighted graph
52+
public int minCostToSupplyWater(int n, int[] wells, int[][] pipes) {
53+
final List<int[]> edges = new ArrayList<>(pipes.length + n + 1);
54+
final DisjointSet disjointSet = new DisjointSet(n + 1);
55+
56+
// add extra vertex and extra edges
57+
for (int i = 0 ; i < n ; i++) {
58+
edges.add(new int[] {0, i + 1, wells[i]});
59+
}
60+
61+
// add preexisting edges
62+
edges.addAll(Arrays.asList(pipes));
63+
64+
// sort edges according to weight
65+
edges.sort(Comparator.comparingInt(a -> a[2]));
66+
67+
int totalCost = 0;
68+
for (int[] edge : edges) {
69+
final int house1 = edge[0], house2 = edge[1], cost = edge[2];
70+
if (!disjointSet.isConnected(house1, house2)) {
71+
disjointSet.union(house1, house2);
72+
totalCost += cost;
73+
n--;
74+
if (n == 0) {
75+
break;
76+
}
77+
}
78+
}
79+
return totalCost;
80+
}
81+
}

0 commit comments

Comments
 (0)