Min Cost to Connect All Points — Problem & Solution
Min Cost to Connect All Points solution explained: step-by-step approach, complexity and code in Python, Java, C++ and JavaScript. A medium problem.
Min Cost to Connect All Points is a medium coding problem on graph, union find and minimum spanning tree, asked in Directi interviews.
- Difficulty: Medium
- Topics: Graph, Union Find, Minimum Spanning Tree
- Asked at: Directi
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
You are given 2D points. The cost of connecting two points is their Manhattan distance |x1-x2| + |y1-y2|.
Return the minimum total cost to make all points connected (exactly one simple path between every pair).
Example 1
Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
Output: 20
Example 2
Input: points = [[3,12],[-2,5],[-4,1]]
Output: 18
Constraints
1 <= points.length <= 10-100 <= coordinates <= 100
Hints for Min Cost to Connect All Points
Hint 1
This is a Minimum Spanning Tree on the complete graph of points.
Hint 2
Prim's algorithm with an array of best-known distances is O(n²) — plenty here.
How to solve Min Cost to Connect All Points
Connecting all points with exactly one path between every pair means building a spanning tree, and "minimum total cost" makes it a Minimum Spanning Tree. Every pair of points is joinable, so the graph is complete — which makes Prim's algorithm with a simple array of best-known distances the natural fit at O(n^2), with no edge list to build.
Approach
- Keep
inTree[v]andminDist[v], the cheapest known edge from the growing tree tov. Start withminDist[0] = 0and everything else infinite. - Repeat
ntimes: pick the point not yet in the tree with the smallestminDist. - Add it to the tree and add its
minDistto the running total. - For every point still outside, recompute its Manhattan distance to the newly added point and keep it if it beats the current
minDist. - After
nrounds every point is connected and the total is the MST cost.
Why it works
Prim's rests on the cut property: for any split of the points into "in the tree" and "not yet", the cheapest edge crossing that split belongs to some MST. Each round picks exactly that edge — minDist holds, for every outside point, the cost of the cheapest edge to the tree, so its minimum is the cheapest crossing edge. Growing the tree one safe edge at a time yields an MST after n - 1 additions; the seed contributes 0.
Complexity
- Time —
O(n^2) - Space —
O(n)
Pitfalls
- A single point costs
0— guard the trivial case so the loop does not add an infiniteminDist. - Update
minDistonly for points outside the tree; touching those already inside can corrupt the running minimum. - The metric is Manhattan (
|dx| + |dy|), not Euclidean. - The seed's
minDistmust be0, otherwise the total is off by the first edge.
Reference solution
Python
from typing import List
def minCostConnectPoints(points: List[List[int]]) -> int:
n = len(points)
if n <= 1:
return 0
INF = float("inf")
in_tree = [False] * n
min_dist = [INF] * n
min_dist[0] = 0
total = 0
for _ in range(n):
u = -1
for v in range(n):
if not in_tree[v] and (u == -1 or min_dist[v] < min_dist[u]):
u = v
in_tree[u] = True
total += min_dist[u]
for v in range(n):
if not in_tree[v]:
d = abs(points[u][0] - points[v][0]) + abs(points[u][1] - points[v][1])
if d < min_dist[v]:
min_dist[v] = d
return totalJava
public static int minCostConnectPoints(int[][] points) {
int n = points.length;
if (n <= 1) return 0;
final int INF = 1000000000;
boolean[] inTree = new boolean[n];
int[] minDist = new int[n];
Arrays.fill(minDist, INF);
minDist[0] = 0;
int total = 0;
for (int iter = 0; iter < n; iter++) {
int u = -1;
for (int v = 0; v < n; v++) {
if (!inTree[v] && (u == -1 || minDist[v] < minDist[u])) u = v;
}
inTree[u] = true;
total += minDist[u];
for (int v = 0; v < n; v++) {
if (!inTree[v]) {
int d = Math.abs(points[u][0] - points[v][0]) + Math.abs(points[u][1] - points[v][1]);
if (d < minDist[v]) minDist[v] = d;
}
}
}
return total;
}C++
int minCostConnectPoints(vector<vector<int>>& points) {
int n = (int) points.size();
if (n <= 1) return 0;
const int INF = 1000000000;
vector<bool> inTree(n, false);
vector<int> minDist(n, INF);
minDist[0] = 0;
int total = 0;
for (int iter = 0; iter < n; iter++) {
int u = -1;
for (int v = 0; v < n; v++) {
if (!inTree[v] && (u == -1 || minDist[v] < minDist[u])) u = v;
}
inTree[u] = true;
total += minDist[u];
for (int v = 0; v < n; v++) {
if (!inTree[v]) {
int d = abs(points[u][0] - points[v][0]) + abs(points[u][1] - points[v][1]);
if (d < minDist[v]) minDist[v] = d;
}
}
}
return total;
}JavaScript
var minCostConnectPoints = function(points) {
const n = points.length;
if (n <= 1) return 0;
const inTree = new Array(n).fill(false);
const minDist = new Array(n).fill(Infinity);
minDist[0] = 0;
let total = 0;
for (let iter = 0; iter < n; iter++) {
let u = -1;
for (let v = 0; v < n; v++) {
if (!inTree[v] && (u === -1 || minDist[v] < minDist[u])) u = v;
}
inTree[u] = true;
total += minDist[u];
for (let v = 0; v < n; v++) {
if (!inTree[v]) {
const d = Math.abs(points[u][0] - points[v][0]) + Math.abs(points[u][1] - points[v][1]);
if (d < minDist[v]) minDist[v] = d;
}
}
}
return total;
};Also on the editorial tab: C, C#, Go, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.
All 107 graph problems · the whole catalogue
Learn the technique: Graph Data Structure · Union-Find (Disjoint Set Union)