Skip to content

Commit 504ffc6

Browse files
committed
Add problem 743 - Network Delay Time
1 parent 48a5423 commit 504ffc6

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package graph
2+
3+
import (
4+
"container/heap"
5+
)
6+
7+
// Edge represents a directed edge with a weight.
8+
type Edge struct {
9+
node, weight int
10+
}
11+
12+
// MinHeap is a priority queue to store nodes and their cumulative distances from the start.
13+
type MinHeap [][]int
14+
15+
// Implement heap.Interface for MinHeap
16+
17+
func (h MinHeap) Len() int {
18+
return len(h)
19+
}
20+
21+
func (h MinHeap) Less(i, j int) bool {
22+
return h[i][0] < h[j][0]
23+
}
24+
25+
func (h MinHeap) Swap(i, j int) {
26+
h[i], h[j] = h[j], h[i]
27+
}
28+
29+
func (h *MinHeap) Push(x interface{}) {
30+
*h = append(*h, x.([]int))
31+
}
32+
33+
func (h *MinHeap) Pop() interface{} {
34+
old := *h
35+
n := len(old)
36+
x := old[n-1]
37+
*h = old[0 : n-1]
38+
return x
39+
}
40+
41+
// networkDelayTime calculates the time it will take for all nodes to receive a signal sent from a given node.
42+
func NetworkDelayTime(times [][]int, n int, k int) int {
43+
// Create the graph using an adjacency list representation.
44+
graph := make(map[int][]Edge)
45+
for _, time := range times {
46+
u, v, w := time[0], time[1], time[2]
47+
graph[u] = append(graph[u], Edge{v, w})
48+
}
49+
50+
// Min-heap to get the node with the shortest cumulative distance first.
51+
minHeap := &MinHeap{}
52+
heap.Init(minHeap)
53+
heap.Push(minHeap, []int{0, k}) // Start with the source node `k` with a distance of 0.
54+
55+
// Visited set to store nodes that have been processed.
56+
visited := make(map[int]bool)
57+
maxDelay := 0
58+
59+
// Process nodes in the heap.
60+
for minHeap.Len() > 0 {
61+
current := heap.Pop(minHeap).([]int)
62+
currentDistance := current[0]
63+
currentNode := current[1]
64+
65+
// Skip processing if the node has already been visited.
66+
if visited[currentNode] {
67+
continue
68+
}
69+
visited[currentNode] = true
70+
maxDelay = currentDistance
71+
72+
// Iterate over all neighbors of the current node.
73+
for _, edge := range graph[currentNode] {
74+
if !visited[edge.node] {
75+
heap.Push(minHeap, []int{currentDistance + edge.weight, edge.node})
76+
}
77+
}
78+
}
79+
80+
// If all nodes are visited, return the maximum delay time; otherwise, return -1.
81+
if len(visited) == n {
82+
return maxDelay
83+
}
84+
return -1
85+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package graph_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/anirudhology/leetcode-go/problems/graph"
7+
)
8+
9+
func TestNetworkDelayTime(t *testing.T) {
10+
// Test case 1: Basic case with all nodes reachable
11+
if res := graph.NetworkDelayTime([][]int{{2, 1, 1}, {2, 3, 1}, {3, 4, 1}}, 4, 2); res != 2 {
12+
t.Errorf("Expected 2, got %d", res)
13+
}
14+
15+
// Test case 2: Node unreachable
16+
if res := graph.NetworkDelayTime([][]int{{1, 2, 1}}, 2, 1); res != 1 {
17+
t.Errorf("Expected 1, got %d", res)
18+
}
19+
20+
// Test case 3: Single node, self delay is 0
21+
if res := graph.NetworkDelayTime([][]int{}, 1, 1); res != 0 {
22+
t.Errorf("Expected 0, got %d", res)
23+
}
24+
25+
// Test case 4: All nodes connected in a line
26+
if res := graph.NetworkDelayTime([][]int{{1, 2, 1}, {2, 3, 1}, {3, 4, 1}}, 4, 1); res != 3 {
27+
t.Errorf("Expected 3, got %d", res)
28+
}
29+
30+
// Test case 5: Empty times array, unreachable nodes
31+
if res := graph.NetworkDelayTime([][]int{}, 2, 1); res != -1 {
32+
t.Errorf("Expected -1, got %d", res)
33+
}
34+
35+
// Test case 6: Cycle in the graph
36+
if res := graph.NetworkDelayTime([][]int{{1, 2, 1}, {2, 3, 2}, {3, 1, 3}}, 3, 1); res != 3 {
37+
t.Errorf("Expected 3, got %d", res)
38+
}
39+
}

0 commit comments

Comments
 (0)