Skip to content

Commit 5062ac4

Browse files
committed
added problem 1514
1 parent 77d0cb6 commit 5062ac4

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package problem1514
2+
3+
/*
4+
You are given an undirected weighted graph of n nodes (0-indexed),
5+
represented by an edge list where edges[i] = [a, b] is an undirected edge connecting the nodes a and b with a
6+
probability of success of traversing that edge succProb[i].
7+
Given two nodes start and end, find the path with the maximum probability of
8+
success to go from start to end and return its success probability.
9+
If there is no path from start to end, return 0.
10+
Your answer will be accepted if it differs from the correct answer by at most 1e-5.
11+
*/
12+
13+
type Pair struct {
14+
Prob float64
15+
Pos int
16+
}
17+
18+
func maxProbability(size int, edges [][]int, succProb []float64, start int, end int) float64 {
19+
var res float64
20+
// Building graph
21+
var graph = make([][]Pair, size)
22+
for i := range edges {
23+
graph[edges[i][0]] = append(graph[edges[i][0]], Pair{succProb[i], edges[i][1]})
24+
graph[edges[i][1]] = append(graph[edges[i][1]], Pair{succProb[i], edges[i][0]})
25+
}
26+
// Cache for probability
27+
var seen = make([]float64, size)
28+
// BFS buckets
29+
var cur, nxt []Pair
30+
cur = []Pair{{1, start}}
31+
// Run BFS until we run out of paths
32+
for len(cur) > 0 {
33+
nxt = nxt[:0]
34+
// For each node in our list
35+
for _, c := range cur {
36+
// Check if we already visited with higher probability
37+
if seen[c.Pos] > c.Prob {
38+
continue
39+
}
40+
// For each potential path from there
41+
for _, n := range graph[c.Pos] {
42+
temp := Pair{c.Prob * n.Prob, n.Pos}
43+
if n.Pos == end {
44+
// Check we reached the end
45+
res = max(res, temp.Prob)
46+
} else {
47+
// Check if we're going to a visited node with higher
48+
// probability
49+
if seen[temp.Pos] >= temp.Prob {
50+
continue
51+
}
52+
// Record the current probability
53+
seen[temp.Pos] = temp.Prob
54+
// Add next node to bucket
55+
nxt = append(nxt, temp)
56+
}
57+
}
58+
}
59+
// Switch buckets
60+
cur, nxt = nxt, cur
61+
}
62+
return res
63+
}
64+
65+
func max(a, b float64) float64 {
66+
if a > b {
67+
return a
68+
}
69+
return b
70+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package problem1514
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
type TestCase struct {
11+
N int
12+
Edges [][]int
13+
Prob []float64
14+
Start, End int
15+
Expected float64
16+
}
17+
18+
var TestCases = []TestCase{
19+
{
20+
N: 3,
21+
Edges: [][]int{{0, 1}, {1, 2}, {0, 2}},
22+
Prob: []float64{0.5, 0.5, 0.2},
23+
Start: 0, End: 2,
24+
Expected: 0.25,
25+
},
26+
{
27+
N: 3,
28+
Edges: [][]int{{0, 1}, {1, 2}, {0, 2}},
29+
Prob: []float64{0.5, 0.5, 0.3},
30+
Start: 0, End: 2,
31+
Expected: 0.3,
32+
},
33+
{
34+
N: 3,
35+
Edges: [][]int{{0, 1}},
36+
Prob: []float64{0.5},
37+
Start: 0, End: 2,
38+
Expected: 0,
39+
},
40+
}
41+
42+
const precision float64 = 0.00001
43+
44+
func TestMaxProbabilityPath(t *testing.T) {
45+
assert := assert.New(t)
46+
47+
for _, tc := range TestCases {
48+
want := tc.Expected
49+
got := maxProbability(tc.N, tc.Edges, tc.Prob, tc.Start, tc.End)
50+
assert.InDelta(want, got, precision, fmt.Sprintf("%+v", tc))
51+
}
52+
}
53+
54+
func BenchmarkMaxProbabilityPath(b *testing.B) {
55+
for i := 0; i < b.N; i++ {
56+
for _, tc := range TestCases {
57+
maxProbability(tc.N, tc.Edges, tc.Prob, tc.Start, tc.End)
58+
}
59+
}
60+
}

readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,7 @@ Each problem is in it's own directory, with test files. There are helper package
426426
| 1496 | [Path Crossing](https://leetcode.com/problems/path-crossing) | [My Solution](./problems/problem1496) ||
427427
| 1498 | [Number of Subsequences That Satisfy the Given Sum Condition](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition) | [My Solution](./problems/problem1498) ||
428428
| 1502 | [Can Make Arithmetic Progression From Sequence](https://leetcode.com/problems/can-make-arithmetic-progression-from-sequence) | [My Solution](./problems/problem1502) ||
429+
| 1514 | [Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability) | [My Solution](./problems/problem1514) ||
429430
| 1519 | [Number of Nodes in the Sub-Tree With the Same Label](https://leetcode.com/problems/number-of-nodes-in-the-sub-tree-with-the-same-label) | [My Solution](./problems/problem1519) ||
430431
| 1523 | [Count Odd Numbers in an Interval Range](https://leetcode.com/problems/count-odd-numbers-in-an-interval-range) | [My Solution](./problems/problem1523) ||
431432
| 1539 | [Kth Missing Positive Number](https://leetcode.com/problems/kth-missing-positive-number) | [My Solution](./problems/problem1539) ||

0 commit comments

Comments
 (0)