Skip to content

Commit 5dfadbe

Browse files
committed
Add problem 1584 - Min Cost to Connect All Points
1 parent b89f11d commit 5dfadbe

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package graph
2+
3+
import "container/heap"
4+
5+
// Edge represents an edge in the graph
6+
type PointsEdge struct {
7+
u, v int
8+
weight int
9+
}
10+
11+
// PriorityQueue implements heap.Interface and holds Edges
12+
type PriorityQueue []*PointsEdge
13+
14+
func (pq PriorityQueue) Len() int { return len(pq) }
15+
16+
func (pq PriorityQueue) Less(i, j int) bool {
17+
return pq[i].weight < pq[j].weight
18+
}
19+
20+
func (pq PriorityQueue) Swap(i, j int) {
21+
pq[i], pq[j] = pq[j], pq[i]
22+
}
23+
24+
func (pq *PriorityQueue) Push(x interface{}) {
25+
item := x.(*PointsEdge)
26+
*pq = append(*pq, item)
27+
}
28+
29+
func (pq *PriorityQueue) Pop() interface{} {
30+
old := *pq
31+
n := len(old)
32+
item := old[n-1]
33+
*pq = old[0 : n-1]
34+
return item
35+
}
36+
37+
func MinCostToConnectAllPoints(points [][]int) int {
38+
// Special case
39+
if len(points) == 0 {
40+
return 0
41+
}
42+
// Total number of points
43+
n := len(points)
44+
// Array to store visited nodes
45+
visited := make([]bool, n)
46+
for i := range visited {
47+
visited[i] = false
48+
}
49+
// We need to visit only n - 1 vertices as we don't want
50+
// cycle in the graph
51+
edgesLeftToVisit := n - 1
52+
// Total cost of connecting points
53+
cost := 0
54+
// Since we always want nearest edge to be chosen first,
55+
// we will use minHeap to store edges by distances
56+
edges := &PriorityQueue{}
57+
heap.Init(edges)
58+
// We will choose first vertex 0 to find cost to reach all
59+
// points from here
60+
for i := 1; i < n; i++ {
61+
distance := Abs(points[i][0]-points[0][0]) + Abs(points[i][1]-points[0][1])
62+
heap.Push(edges, &PointsEdge{u: 0, v: i, weight: distance})
63+
}
64+
// Mark 0 node as visited
65+
visited[0] = true
66+
// Process edges until edgesLeftToVisit becomes 0
67+
for edges.Len() > 0 && edgesLeftToVisit > 0 {
68+
// Get current edge
69+
edge := heap.Pop(edges).(*PointsEdge)
70+
v, weight := edge.v, edge.weight
71+
if !visited[v] {
72+
// Add the cost and mark as visited
73+
cost += weight
74+
visited[v] = true
75+
// Now traverse all possible points from v
76+
for i := 0; i < n; i++ {
77+
if !visited[i] {
78+
distance := Abs(points[i][0]-points[v][0]) + Abs(points[i][1]-points[v][1])
79+
heap.Push(edges, &PointsEdge{u: v, v: i, weight: distance})
80+
}
81+
}
82+
edgesLeftToVisit--
83+
}
84+
}
85+
return cost
86+
}
87+
88+
func Abs(a int) int {
89+
if a < 0 {
90+
return -a
91+
}
92+
return a
93+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package graph_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/anirudhology/leetcode-go/problems/graph"
7+
)
8+
9+
func TestMinCostConnectPoints_EmptyInput(t *testing.T) {
10+
points := [][]int{}
11+
result := graph.MinCostToConnectAllPoints(points)
12+
if result != 0 {
13+
t.Errorf("Expected 0, but got %d", result)
14+
}
15+
}
16+
17+
func TestMinCostConnectPoints_SinglePoint(t *testing.T) {
18+
points := [][]int{{0, 0}}
19+
result := graph.MinCostToConnectAllPoints(points)
20+
if result != 0 {
21+
t.Errorf("Expected 0, but got %d", result)
22+
}
23+
}
24+
25+
func TestMinCostConnectPoints_TwoPoints(t *testing.T) {
26+
points := [][]int{{0, 0}, {1, 1}}
27+
result := graph.MinCostToConnectAllPoints(points)
28+
if result != 2 {
29+
t.Errorf("Expected 2, but got %d", result)
30+
}
31+
}
32+
33+
func TestMinCostConnectPoints_MultiplePoints(t *testing.T) {
34+
points := [][]int{{0, 0}, {2, 2}, {3, 10}, {5, 2}, {7, 0}}
35+
result := graph.MinCostToConnectAllPoints(points)
36+
if result != 20 {
37+
t.Errorf("Expected 20, but got %d", result)
38+
}
39+
}
40+
41+
func TestMinCostConnectPoints_NegativePoints(t *testing.T) {
42+
points := [][]int{{-1, -2}, {1, 3}, {4, 5}}
43+
result := graph.MinCostToConnectAllPoints(points)
44+
if result != 12 {
45+
t.Errorf("Expected 12, but got %d", result)
46+
}
47+
}

0 commit comments

Comments
 (0)