Skip to content

Commit 331e17a

Browse files
authored
Merge pull request #1496 from Hitesh4278/path-with-maximum-probability
Added the Solution of Path with Maximum Probability - Issue No 1439
2 parents ef5aae5 + ce63a88 commit 331e17a

File tree

2 files changed

+355
-1
lines changed

2 files changed

+355
-1
lines changed

dsa-problems/leetcode-problems/1500-1599.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export const problems = [
9898
"problemName": "1514. Path with Maximum Probability",
9999
"difficulty": "Medium",
100100
"leetCodeLink": "https://leetcode.com/problems/path-with-maximum-probability",
101-
"solutionLink": "#"
101+
"solutionLink": "/dsa-solutions/lc-solutions/1400-1499/path-with-maximum-probability"
102102
},
103103
{
104104
"problemName": "1515. Best Position for a Service Centre",
Lines changed: 354 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,354 @@
1+
---
2+
id: path-with-maximum-probability
3+
title: Path with Maximum Probability
4+
sidebar_label: 1514 - Path with Maximum Probability
5+
tags:
6+
- Array
7+
- Graph
8+
- Heap (Priority Queue)
9+
- Shortest Path
10+
description: "This is a solution to the Path with Maximum Probability problem on LeetCode."
11+
---
12+
13+
## Problem Description
14+
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].
15+
16+
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.
17+
18+
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.
19+
20+
### Examples
21+
**Example 1:**
22+
![image](https://assets.leetcode.com/uploads/2019/09/20/1558_ex1.png)
23+
```
24+
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2
25+
Output: 0.25000
26+
Explanation: There are two paths from start to end, one having a probability of success = 0.2 and the other has 0.5 * 0.5 = 0.25.
27+
28+
```
29+
30+
**Example 2:**
31+
![image](https://assets.leetcode.com/uploads/2019/09/20/1558_ex2.png)
32+
33+
```
34+
Input: n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2
35+
Output: 0.30000
36+
```
37+
38+
### Constraints
39+
- `2 <= n <= 10^4`
40+
- `0 <= start, end < n`
41+
- `start != end`
42+
- `0 <= a, b < n`
43+
- `a != b`
44+
- `0 <= succProb.length == edges.length <= 2*10^4`
45+
- `0 <= succProb[i] <= 1`
46+
- `There is at most one edge between every two nodes.`
47+
## Solution for Path with Maximum Probability Problem
48+
### Approach
49+
#### Main Intuition
50+
The main intuition behind this code is similar to Dijkstra's algorithm for finding the shortest path, but instead of minimizing distances, it maximizes probabilities. The idea is to iteratively explore the most probable paths using a priority queue to always expand the most promising node (the node with the highest probability of being part of the maximum probability path to the end node).
51+
52+
#### Graph Representation:
53+
54+
- The graph is represented using an adjacency list. Each node has a list of pairs, where each pair consists of an adjacent node and the probability of successfully traversing the edge to that node.
55+
#### Input Parsing:
56+
57+
- The number of nodes (n) and the edges along with their respective probabilities (edges and succProb) are given as input.
58+
- The start and end nodes are also provided.
59+
#### Building the Graph:
60+
61+
- A vector of vectors of pairs (adj) is created to store the adjacency list.
62+
- For each edge, two entries are added to the adjacency list to ensure the graph is undirected. Each entry contains the adjacent node and the probability of traversing that edge.
63+
#### Probability Initialization:
64+
65+
- A prob vector is initialized to store the maximum probability of reaching each node from the start node. It is initialized to 0.0 for all nodes.
66+
- The probability of reaching the start node from itself is set to 1.0 (prob[start] = 1.0).
67+
#### Priority Queue for Processing Nodes:
68+
69+
- A priority queue (pq) is used to process nodes. This queue helps in processing nodes in the order of their probabilities (although the current implementation uses a max-heap for integer priorities, which is not correct and should use a min-heap for probabilities).
70+
#### Dijkstra-like Algorithm:
71+
72+
- The algorithm processes nodes from the priority queue. For each node, it checks all its adjacent nodes.
73+
- For each adjacent node, it calculates the probability of reaching it through the current node (prob[node] * probab).
74+
- If this new probability is higher than the currently known probability for the adjacent node, it updates the probability and pushes the adjacent node into the priority queue.
75+
#### Result:
76+
77+
- After processing all reachable nodes, the maximum probability to reach the end node is found in prob[end].
78+
<Tabs>
79+
<TabItem value="Solution" label="Solution">
80+
81+
#### Implementation
82+
```jsx live
83+
function Solution(arr) {
84+
var maxProbability = function(n, edges, succProb, start, end) {
85+
const p = Array(n).fill(0);
86+
const graph = p.reduce((m, _, i) => m.set(i, []), new Map());
87+
edges.forEach(([u, v], i) => {
88+
graph.get(u).push([v, succProb[i]]);
89+
graph.get(v).push([u, succProb[i]]);
90+
});
91+
92+
const queue = [[start, 1]];
93+
p[start] = 1;
94+
95+
for (let [node, currP] of queue) {
96+
for (let [adj, nextP] of graph.get(node)) {
97+
if (currP * nextP > p[adj]) {
98+
p[adj] = currP * nextP;
99+
queue.push([adj, p[adj]]);
100+
}
101+
}
102+
}
103+
104+
return p[end];
105+
};
106+
const input = [[0,1],[1,2],[0,2]]
107+
const n = 3
108+
const succProb = [0.5,0.5,0.2]
109+
const start=0;
110+
const end =2
111+
const output = maxProbability(n, input , succProb,start , end)
112+
return (
113+
<div>
114+
<p>
115+
<b>Input: </b>
116+
{JSON.stringify(input)}
117+
</p>
118+
<p>
119+
<b>Output:</b> {output.toString()}
120+
</p>
121+
</div>
122+
);
123+
}
124+
```
125+
126+
#### Complexity Analysis
127+
128+
- Time Complexity: $O(edges*log(n)) $
129+
- Space Complexity: $ O(n)$
130+
131+
## Code in Different Languages
132+
<Tabs>
133+
<TabItem value="JavaScript" label="JavaScript">
134+
<SolutionAuthor name="@hiteshgahanolia"/>
135+
```javascript
136+
function maxProbability(n, edges, succProb, start, end) {
137+
let adj = Array.from({ length: n }, () => []);
138+
139+
for (let i = 0; i < edges.length; i++) {
140+
adj[edges[i][0]].push([edges[i][1], succProb[i]]);
141+
adj[edges[i][1]].push([edges[i][0], succProb[i]]);
142+
}
143+
144+
let prob = new Array(n).fill(0.0);
145+
let pq = new MaxPriorityQueue({ priority: x => x[1] });
146+
147+
prob[start] = 1.0;
148+
pq.enqueue([start, 1.0]);
149+
150+
while (!pq.isEmpty()) {
151+
let [node, nodeProb] = pq.dequeue().element;
152+
153+
for (let [adjNode, probab] of adj[node]) {
154+
if (prob[node] * probab > prob[adjNode]) {
155+
prob[adjNode] = prob[node] * probab;
156+
pq.enqueue([adjNode, prob[adjNode]]);
157+
}
158+
}
159+
}
160+
161+
return prob[end];
162+
}
163+
164+
```
165+
166+
</TabItem>
167+
<TabItem value="TypeScript" label="TypeScript">
168+
<SolutionAuthor name="@hiteshgahanolia"/>
169+
```typescript
170+
class Solution {
171+
maxProbability(n: number, edges: number[][], succProb: number[], start: number, end: number): number {
172+
let adj: Array<[number, number][]> = Array.from({ length: n }, () => []);
173+
174+
for (let i = 0; i < edges.length; i++) {
175+
adj[edges[i][0]].push([edges[i][1], succProb[i]]);
176+
adj[edges[i][1]].push([edges[i][0], succProb[i]]);
177+
}
178+
179+
let prob: number[] = new Array(n).fill(0.0);
180+
let pq = new MaxPriorityQueue({ priority: (x: [number, number]) => x[1] });
181+
182+
prob[start] = 1.0;
183+
pq.enqueue([start, 1.0]);
184+
185+
while (!pq.isEmpty()) {
186+
let [node, nodeProb] = pq.dequeue().element;
187+
188+
for (let [adjNode, probab] of adj[node]) {
189+
if (prob[node] * probab > prob[adjNode]) {
190+
prob[adjNode] = prob[node] * probab;
191+
pq.enqueue([adjNode, prob[adjNode]]);
192+
}
193+
}
194+
}
195+
196+
return prob[end];
197+
}
198+
}
199+
200+
```
201+
</TabItem>
202+
<TabItem value="Python" label="Python">
203+
<SolutionAuthor name="@hiteshgahanolia"/>
204+
```python
205+
import heapq
206+
from typing import List
207+
208+
class Solution:
209+
def maxProbability(self, n: int, edges: List[List[int]], succProb: List[float], start: int, end: int) -> float:
210+
adj = [[] for _ in range(n)]
211+
212+
for i in range(len(edges)):
213+
adj[edges[i][0]].append((edges[i][1], succProb[i]))
214+
adj[edges[i][1]].append((edges[i][0], succProb[i]))
215+
216+
prob = [0.0] * n
217+
pq = []
218+
219+
prob[start] = 1.0
220+
heapq.heappush(pq, (-1.0, start))
221+
222+
while pq:
223+
nodeProb, node = heapq.heappop(pq)
224+
nodeProb = -nodeProb
225+
226+
for adjNode, probab in adj[node]:
227+
if prob[node] * probab > prob[adjNode]:
228+
prob[adjNode] = prob[node] * probab
229+
heapq.heappush(pq, (-prob[adjNode], adjNode))
230+
231+
return prob[end]
232+
233+
```
234+
235+
</TabItem>
236+
<TabItem value="Java" label="Java">
237+
<SolutionAuthor name="@hiteshgahanolia"/>
238+
```java
239+
import java.util.*;
240+
241+
class Solution {
242+
public double maxProbability(int n, int[][] edges, double[] succProb, int start, int end) {
243+
List<Pair<Integer, Double>>[] adj = new ArrayList[n];
244+
for (int i = 0; i < n; i++) {
245+
adj[i] = new ArrayList<>();
246+
}
247+
248+
for (int i = 0; i < edges.length; i++) {
249+
adj[edges[i][0]].add(new Pair<>(edges[i][1], succProb[i]));
250+
adj[edges[i][1]].add(new Pair<>(edges[i][0], succProb[i]));
251+
}
252+
253+
double[] prob = new double[n];
254+
PriorityQueue<Pair<Integer, Double>> pq = new PriorityQueue<>((a, b) -> Double.compare(b.getValue(), a.getValue()));
255+
256+
prob[start] = 1.0;
257+
pq.add(new Pair<>(start, 1.0));
258+
259+
while (!pq.isEmpty()) {
260+
Pair<Integer, Double> nodePair = pq.poll();
261+
int node = nodePair.getKey();
262+
double nodeProb = nodePair.getValue();
263+
264+
for (Pair<Integer, Double> it : adj[node]) {
265+
int adjNode = it.getKey();
266+
double probab = it.getValue();
267+
268+
if (prob[node] * probab > prob[adjNode]) {
269+
prob[adjNode] = prob[node] * probab;
270+
pq.add(new Pair<>(adjNode, prob[adjNode]));
271+
}
272+
}
273+
}
274+
275+
return prob[end];
276+
}
277+
278+
static class Pair<K, V> {
279+
private final K key;
280+
private final V value;
281+
282+
public Pair(K key, V value) {
283+
this.key = key;
284+
this.value = value;
285+
}
286+
287+
public K getKey() {
288+
return key;
289+
}
290+
291+
public V getValue() {
292+
return value;
293+
}
294+
}
295+
}
296+
297+
```
298+
299+
</TabItem>
300+
<TabItem value="C++" label="C++">
301+
<SolutionAuthor name="@hiteshgahanolia"/>
302+
```cpp
303+
class Solution {
304+
public:
305+
double maxProbability(int n, vector<vector<int>>& edges, vector<double>& succProb, int start, int end) {
306+
vector<pair<int,double>>adj[n];
307+
308+
for(int i=0;i<edges.size();i++)
309+
{
310+
adj[edges[i][0]].push_back({edges[i][1],succProb[i]});
311+
adj[edges[i][1]].push_back({edges[i][0],succProb[i]});
312+
}
313+
314+
vector<double>prob(n,0.0);
315+
priority_queue<int> pq;
316+
317+
prob[start]=1.0;
318+
319+
pq.push(start);
320+
321+
while(!pq.empty())
322+
{
323+
int node= pq.top();
324+
pq.pop();
325+
326+
for(auto it: adj[node])
327+
{
328+
int adjNode=it.first;
329+
double probab=it.second;
330+
331+
if(prob[node]*probab>prob[adjNode] )
332+
{
333+
pq.push(adjNode);
334+
prob[adjNode]=prob[node]*probab;
335+
}
336+
}
337+
}
338+
339+
return prob[end];
340+
}
341+
};
342+
```
343+
</TabItem>
344+
</Tabs>
345+
346+
</TabItem>
347+
</Tabs>
348+
349+
## References
350+
351+
- **LeetCode Problem**: [Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability)
352+
353+
- **Solution Link**: [LeetCode Solution](https://leetcode.com/problems/path-with-maximum-probability/solutions)
354+

0 commit comments

Comments
 (0)