diff --git a/internal/Leetcode/1514/1514.go b/internal/Leetcode/1514/1514.go new file mode 100644 index 0000000..9b1fcff --- /dev/null +++ b/internal/Leetcode/1514/1514.go @@ -0,0 +1,55 @@ +package _1514 + +import ( + "container/heap" +) + +func maxProbability(n int, edges [][]int, succProb []float64, start_node int, end_node int) float64 { + // 2 dim array with map + graph := make([]map[int]float64, n) + for i := range graph { + graph[i] = make(map[int]float64) + } + //maxHeap as priority queue + maxHeap := make(PriorityQueue, 0) + //init graph + maxHeap.Push(&Item{value: start_node, priority: 1}) + + seen := make([]bool, n) + + for i := range edges { + u := edges[i][0] + v := edges[i][1] + prob := succProb[i] + //graph = append(graph, map[int]float64{v: prob}) + //graph = append(graph, map[int]float64{u: prob}) + graph[u][v] = prob + graph[v][u] = prob + + } + + for maxHeap.Len() > 0 { + item := heap.Pop(&maxHeap).(*Item) + prob := item.priority + u := item.value + + if u == end_node { + return prob + } + + if seen[u] { + continue + } + + seen[u] = true + + for nextNode, edgeProb := range graph[u] { + if seen[nextNode] { + continue + } + heap.Push(&maxHeap, &Item{value: nextNode, priority: prob * edgeProb}) + } + } + + return 0.0 +} diff --git a/internal/Leetcode/1514/1514_test.go b/internal/Leetcode/1514/1514_test.go new file mode 100644 index 0000000..204e59e --- /dev/null +++ b/internal/Leetcode/1514/1514_test.go @@ -0,0 +1,39 @@ +package _1514 + +import ( + "testing" +) + +func Test_maxProbability(t *testing.T) { + type args struct { + n int + edges [][]int + succProb []float64 + start_node int + end_node int + } + tests := []struct { + name string + args args + want float64 + }{ + { + name: "test case 1", + args: args{ + n: 3, + edges: [][]int{{0, 1}, {1, 2}, {0, 2}}, + succProb: []float64{0.5, 0.5, 0.2}, + start_node: 0, + end_node: 2, + }, + want: 0.25, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := maxProbability(tt.args.n, tt.args.edges, tt.args.succProb, tt.args.start_node, tt.args.end_node); got != tt.want { + t.Errorf("maxProbability() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/Leetcode/1514/PriorityQueue.go b/internal/Leetcode/1514/PriorityQueue.go new file mode 100644 index 0000000..a450a0c --- /dev/null +++ b/internal/Leetcode/1514/PriorityQueue.go @@ -0,0 +1,34 @@ +package _1514 + +// An Item is something we manage in a priority queue. +type Item struct { + value int + priority float64 +} + +// A PriorityQueue implements heap.Interface and holds Items. +type PriorityQueue []*Item + +func (pq PriorityQueue) Len() int { return len(pq) } + +func (pq PriorityQueue) Less(i, j int) bool { + // We want Pop to give us the highest, not lowest, priority so we use greater than here. + return pq[i].priority > pq[j].priority +} + +func (pq PriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] +} + +func (pq *PriorityQueue) Push(x interface{}) { + item := x.(*Item) + *pq = append(*pq, item) +} + +func (pq *PriorityQueue) Pop() interface{} { + old := *pq + n := len(old) + item := old[n-1] + *pq = old[0 : n-1] + return item +}