-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path1514-Path_with_Maximum_Probability.java
More file actions
142 lines (133 loc) · 4.42 KB
/
1514-Path_with_Maximum_Probability.java
File metadata and controls
142 lines (133 loc) · 4.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*******************************************************************************
* 1514-Path_with_Maximum_Probability.java
* Billy.Ljm
* 28 June 2023
*
* =======
* Problem
* =======
* https://leetcode.com/problems/path-with-maximum-probability/
*
* You are given an undirected weighted graph of n nodes (0-indexed),
* represented by an edge list where edges[i] = [a, b] is an undirected edge
* connecting the nodes a and b with a probability of success of traversing that
* edge succProb[i].
*
* Given two nodes start and end, find the path with the maximum probability of
* success to go from start to end and return its success probability.
*
* If there is no path from start to end, return 0. Your answer will be accepted
* if it differs from the correct answer by at most 1e-5.
*
* ===========
* My Approach
* ===========
* We'll use Dijkstra's algorithm, calculating the probability from the start
* node to every other node, in decreasing order of probability. We'll use a
* priority queue to select the highest probability node, and a hashset to
* remember the visited nodes.
*
* This would have a time complexity of O(e + n log n) and space complexity of
* O(e + n), where e and n are the number of edges and nodes respectively.
******************************************************************************/
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
class Solution {
/**
* Finds the path of maximum probability from start to end
* @param n number of nodes
* @param edges list of undirected edges as [from, to]
* @param succProb success probability of each undirected edge
* @param start node to start at
* @param end node to end at
* @return maximum probability of success of travelling from start to end
*/
public double maxProbability(int n, int[][] edges, double[] succProb,
int start, int end) {
// create adjacency matrix
Map<Integer, List<double[]>> adj = new HashMap<>(n);
for (int i = 0; i < edges.length; i++) {
adj.putIfAbsent(edges[i][0], new ArrayList<>());
adj.putIfAbsent(edges[i][1], new ArrayList<>());
adj.get(edges[i][0]).add(new double[] {edges[i][1], succProb[i]});
adj.get(edges[i][1]).add(new double[] {edges[i][0], succProb[i]});
}
// create priority queue and hashset
Set<Integer> visited = new HashSet<>();
PriorityQueue<double[]> pq = new PriorityQueue<>((a, b) -> {
return Double.compare(b[1], a[1]);
});
pq.offer(new double[] {start, 1.0});
// explore nodes in decreasing order of probability
while (!pq.isEmpty()) {
// get node with highest probability
double[] ele = pq.poll();
int node = (int) ele[0];
double prob = ele[1];
// ignore visited nodes
if (visited.contains(node)) continue;
// if end node reached, return
else if (node == end) return prob;
// else add all neighbours
else {
visited.add(node);
if (adj.get(node) == null) continue;
for (double[] neighbour : adj.get(node)) {
if (!visited.contains((int) neighbour[0])) {
pq.offer(new double[] {neighbour[0],
prob * neighbour[1]});
}
}
}
}
// no path found
return 0.0;
}
}
class Test {
/**
* Test cases
*/
public static void main(String[] args) {
Solution sol = new Solution();
int[][] edges;
double[] succProb;
int n, start, end;
// test case 1
edges = new int[][] {{0,1},{1,2},{0,2}};
succProb = new double[] {0.5,0.5,0.2};
n = 3;
start = 0;
end = 2;
System.out.println("maxProbability(" + n + ", "
+ Arrays.deepToString(edges) + ", " + Arrays.toString(succProb)
+ ", " + start + ", " + end + ") = "
+ sol.maxProbability(n, edges, succProb, start, end));
// test case 2
edges = new int[][] {{0,1},{1,2},{0,2}};
succProb = new double[] {0.5,0.5,0.3};
n = 3;
start = 0;
end = 2;
System.out.println("maxProbability(" + n + ", "
+ Arrays.deepToString(edges) + ", " + Arrays.toString(succProb)
+ ", " + start + ", " + end + ") = "
+ sol.maxProbability(n, edges, succProb, start, end));
// test case 3
edges = new int[][] {{0,1}};
succProb = new double[] {0.5};
n = 3;
start = 0;
end = 2;
System.out.println("maxProbability(" + n + ", "
+ Arrays.deepToString(edges) + ", " + Arrays.toString(succProb)
+ ", " + start + ", " + end + ") = "
+ sol.maxProbability(n, edges, succProb, start, end));
}
}