You are given an array points representing integer coordinates of some points on a 2D-plane, where points[i] = [xi, yi]
.
The cost of connecting two points [xi, yi]
and [xj, yj]
is the manhattan distance between them:
|xi - xj| + |yi - yj|
where |val|
denotes the absolute value of val
.
Return the minimum cost to make all points connected. All points are connected if there is exactly one simple path between any two points.
Test Cases
Example 1:


Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
Output: 20
Explanation:
We can connect the points as shown above to get the minimum cost of 20.
Notice that there is a unique path between every pair of points.
Example 2:
Input: points = [[3,12],[-2,5],[-4,1]]
Output: 18
Solution
class UnionFind {
public int[] group;
public int[] rank;
public UnionFind(int size) {
group = new int[size];
rank = new int[size];
for (int i = 0; i < size; ++i) {
group[i] = i;
}
}
public int find(int node) {
if (group[node] != node) {
group[node] = find(group[node]);
}
return group[node];
}
public boolean union(int node1, int node2) {
int group1 = find(node1);
int group2 = find(node2);
// node1 and node2 already belong to same group.
if (group1 == group2) {
return false;
}
if (rank[group1] > rank[group2]) {
group[group2] = group1;
} else if (rank[group1] < rank[group2]) {
group[group1] = group2;
} else {
group[group1] = group2;
rank[group2] += 1;
}
return true;
}
}
class Solution {
public int minCostConnectPoints(int[][] points) {
int n = points.length;
ArrayList<int[]> allEdges = new ArrayList<>();
// Storing all edges of our complete graph.
for (int currNext = 0; currNext < n; ++currNext) {
for (int nextNext = currNext + 1; nextNext < n; ++nextNext) {
int weight = Math.abs(points[currNext][0] - points[nextNext][0]) +
Math.abs(points[currNext][1] - points[nextNext][1]);
int[] currEdge = {weight, currNext, nextNext};
allEdges.add(currEdge);
}
}
// Sort all edges in increasing order.
Collections.sort(allEdges, (a, b) -> Integer.compare(a[0], b[0]));
UnionFind uf = new UnionFind(n);
int mstCost = 0;
int edgesUsed = 0;
for (int i = 0; i < allEdges.size() && edgesUsed < n - 1; ++i) {
int node1 = allEdges.get(i)[1];
int node2 = allEdges.get(i)[2];
int weight = allEdges.get(i)[0];
if (uf.union(node1, node2)) {
mstCost += weight;
edgesUsed++;
}
}
return mstCost;
}
}