Min Cost to Connect All Points medium
Problem Statement
You are given an array points
where points[i] = [xi, yi]
represents the coordinates of the ith point on a 2D plane. The cost of connecting two points points[i]
and points[j]
is the manhattan distance between them: |xi - xj| + |yi - yj|
.
Return the minimum cost to connect all points such that there is a path between any two points.
Example 1
Input: points = [[0,0],[2,2],[3,10],[5,2],[7,0]] Output: 20 Explanation:
We can connect the points as follows:
- (0,0) to (2,2) with cost 4.
- (2,2) to (5,2) with cost 3.
- (5,2) to (7,0) with cost 5.
- (7,0) to (3,10) with cost 14. Total minimum cost = 4 + 3 + 5 + 8 = 20
Example 2
Input: points = [[3,12],[-2,5],[-4,1]] Output: 18
Steps
- Calculate distances: Compute the Manhattan distance between all pairs of points.
- Mininum Spanning Tree (MST): Use Prim's or Kruskal's algorithm to find the minimum spanning tree. This algorithm efficiently finds the minimum set of edges that connect all vertices (points) without forming cycles.
- Sum of edge weights: The sum of the weights (distances) of the edges in the MST is the minimum cost to connect all points.
Explanation
This problem is a classic Minimum Spanning Tree (MST) problem. We need to find the cheapest way to connect all points such that there's a path between any two. A MST guarantees this. Prim's and Kruskal's algorithms are efficient ways to solve this. We'll use Prim's algorithm here for its relative simplicity in implementation.
Prim's Algorithm:
- Start with an arbitrary point.
- Repeatedly add the nearest unconnected point to the MST until all points are connected. The "nearest" is determined by the Manhattan distance.
Code
function minCostConnectPoints(points: number[][]): number {
const n = points.length;
if (n <= 1) return 0;
// Adjacency matrix to store distances. Infinity represents no direct connection.
const adjMatrix: number[][] = Array(n).fill(null).map(() => Array(n).fill(Infinity));
// Calculate Manhattan distances
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
const dist = Math.abs(points[i][0] - points[j][0]) + Math.abs(points[i][1] - points[j][1]);
adjMatrix[i][j] = adjMatrix[j][i] = dist;
}
}
// Prim's algorithm
const minCost = 0;
const visited: boolean[] = Array(n).fill(false);
const minEdge: number[] = Array(n).fill(Infinity);
minEdge[0] = 0; // Start from the first point.
for (let i = 0; i < n; i++) {
let minIndex = -1;
for (let j = 0; j < n; j++) {
if (!visited[j] && (minIndex === -1 || minEdge[j] < minEdge[minIndex])) {
minIndex = j;
}
}
if (minIndex !== -1) {
minCost += minEdge[minIndex];
visited[minIndex] = true;
for (let j = 0; j < n; j++) {
if (!visited[j] && adjMatrix[minIndex][j] < minEdge[j]) {
minEdge[j] = adjMatrix[minIndex][j];
}
}
}
}
return minCost;
};
Complexity
- Time Complexity: O(N^2), where N is the number of points. This is dominated by the distance calculation and Prim's algorithm.
- Space Complexity: O(N^2) to store the adjacency matrix. Could be optimized to O(N) using a different data structure if you don't need to store all distances at once. However, the adjacency matrix makes Prim's algorithm easier to implement.