Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commiteca482d

Browse files
committed
1514-path-with-maximum-probability.md Added Python solution.
1 parentb9ecf44 commiteca482d

File tree

8 files changed

+461
-0
lines changed

8 files changed

+461
-0
lines changed

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,5 +114,6 @@ You can skip the more difficult problems and do them later.
114114
-[685. Redundant Connection II](en/1-1000/685-redundant-connection-ii.md) was solved in_Python_.
115115
-[1584. Min Cost to Connect All Points](en/1001-2000/1584-min-cost-to-connect-all-points.md) was solved in_Python, Java, C++, JavaScript, C#, Go, Ruby_ and 2 ways.
116116
-[207. Course Schedule](en/1-1000/207-course-schedule.md) was solved in_Python, Java, C++, C#_ and 2 ways.
117+
-[1514. Path with Maximum Probability](en/1001-2000/1514-path-with-maximum-probability.md) was solved in_Python_ and 2 ways.
117118

118119
More LeetCode problems will be added soon...
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
#1514. Path with Maximum Probability - Best Practices of LeetCode Solutions
2+
LeetCode link:[1514. Path with Maximum Probability](https://leetcode.com/problems/path-with-maximum-probability), difficulty:**Medium**.
3+
4+
##LeetCode description of "1514. Path with Maximum Probability"
5+
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]`.
6+
7+
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.
8+
9+
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**.
10+
11+
###[Example 1]
12+
![](../../images/examples/1514_1.png)
13+
14+
**Input**:`n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.2], start = 0, end = 2`
15+
16+
**Output**:`0.25000`
17+
18+
**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.`
19+
20+
###[Example 2]
21+
![](../../images/examples/1514_2.png)
22+
23+
**Input**:`n = 3, edges = [[0,1],[1,2],[0,2]], succProb = [0.5,0.5,0.3], start = 0, end = 2`
24+
25+
**Output**:`0.30000`
26+
27+
###[Example 3]
28+
![](../../images/examples/1514_3.png)
29+
30+
**Input**:`n = 3, edges = [[0,1]], succProb = [0.5], start = 0, end = 2`
31+
32+
**Output**:`0.00000`
33+
34+
**Explanation**:`There is no path between 0 and 2.`
35+
36+
###[Constraints]
37+
-`2 <= n <= 10^4`
38+
-`0 <= start, end < n`
39+
-`start != end`
40+
-`0 <= a, b < n`
41+
-`a != b`
42+
-`0 <= succProb.length == edges.length <= 2*10^4`
43+
-`0 <= succProb[i] <= 1`
44+
- There is at most one edge between every two nodes.
45+
46+
###[Hints]
47+
<details>
48+
<summary>Hint 1</summary>
49+
Multiplying probabilities will result in precision errors.
50+
</details>
51+
52+
<details>
53+
<summary>Hint 2</summary>
54+
Take log probabilities to sum up numbers instead of multiplying them.
55+
</details>
56+
57+
<details>
58+
<summary>Hint 3</summary>
59+
Use Dijkstra's algorithm to find the minimum path between the two nodes after negating all costs.
60+
</details>
61+
62+
##Intuition
63+
We can use**Dijkstra's algorithm**.
64+
65+
![](../../images/graph_Dijkstra_algorithm_animation.gif)
66+
67+
This animation is about**Dijkstra's algorithm** to find the shortest path between`a` and`b`.
68+
It picks the unvisited vertex with the lowest distance, calculates the distance through it to each unvisited neighbor, and updates the neighbor's distance if smaller. Mark**visited** (set to red) when done with neighbors.
69+
70+
In short,**Dijkstra's algorithm** means**to find the nearest point and walk through it, and never go back. Repeatedly**.
71+
72+
##Complexity
73+
**V**: vertex count,**E**: Edge count.
74+
75+
###Dijkstra's algorithm without using`heap sort`
76+
* Time:`O(V * V)`.
77+
* Space:`O(V + E)`.
78+
79+
###Dijkstra's algorithm using`heap sort`
80+
* Time:`O(E * log(E))`.
81+
* Space:`O(V + E)`.
82+
83+
##Python
84+
###Dijkstra's algorithm without using`heap sort`
85+
The code will time out when executed on LeetCode, but this is not a problem with the code itself. The`heap sort` implementation below will not time out.
86+
```python
87+
classSolution:
88+
defmaxProbability(self,n:int,edges: List[List[int]],succ_prob: List[float],start_node:int,end_node:int) ->float:
89+
node_to_pairs= defaultdict(set)
90+
91+
for i, (source_node, target_node)inenumerate(edges):
92+
node_to_pairs[source_node].add((target_node, succ_prob[i]))
93+
node_to_pairs[target_node].add((source_node, succ_prob[i]))
94+
95+
max_probabilities= [0]* n
96+
max_probabilities[start_node]=1
97+
visited= [False]* n
98+
99+
for _inrange(n-1):
100+
current_node=None
101+
maximum_probability=0
102+
103+
for node, probabilityinenumerate(max_probabilities):
104+
ifnot visited[node]and probability> maximum_probability:
105+
maximum_probability= probability
106+
current_node= node
107+
108+
if current_nodeisNone:
109+
break
110+
111+
visited[current_node]=True
112+
113+
for target_node, probabilityin node_to_pairs[current_node]:
114+
probability_= probability* max_probabilities[current_node]
115+
116+
if probability_> max_probabilities[target_node]:
117+
max_probabilities[target_node]= probability_
118+
119+
return max_probabilities[end_node]
120+
```
121+
122+
###Dijkstra's algorithm using`heap sort`
123+
####1.`heap sort` without using`visited`
124+
```python
125+
import heapq
126+
127+
classSolution:
128+
defmaxProbability(self,n:int,edges: List[List[int]],succ_prob: List[float],start_node:int,end_node:int) ->float:
129+
node_to_pairs= defaultdict(set)
130+
131+
for i, (source_node, target_node)inenumerate(edges):
132+
node_to_pairs[source_node].add((target_node, succ_prob[i]))
133+
node_to_pairs[target_node].add((source_node, succ_prob[i]))
134+
135+
max_probabilities= [0for nodeinrange(n)]
136+
max_probabilities[start_node]=1
137+
items= [(-1, start_node)]
138+
139+
while items:
140+
current_probability, current_node= heapq.heappop(items)
141+
142+
if current_node== end_node:
143+
return-current_probability
144+
145+
for target_node, probabilityin node_to_pairs[current_node]:
146+
probability_=abs(current_probability)* probability
147+
148+
if probability_> max_probabilities[target_node]:
149+
max_probabilities[target_node]= probability_
150+
# It may cause the same `target_node` added into `items` more than once, but it doesn't matter. Because only the one `heappush`ed first may change the `max_probabilities` data.
151+
heapq.heappush(items, (-probability_, target_node))
152+
153+
return0
154+
```
155+
156+
####2.`heap sort` using`visited`
157+
```python
158+
import heapq
159+
160+
classSolution:
161+
defmaxProbability(self,n:int,edges: List[List[int]],succ_prob: List[float],start_node:int,end_node:int) ->float:
162+
node_to_pairs= defaultdict(set)
163+
164+
for i, (source_node, target_node)inenumerate(edges):
165+
node_to_pairs[source_node].add((target_node, succ_prob[i]))
166+
node_to_pairs[target_node].add((source_node, succ_prob[i]))
167+
168+
max_probabilities= [0for nodeinrange(n)]
169+
max_probabilities[start_node]=1
170+
items= [(-1, start_node)]
171+
visited= [False]* n# added 1
172+
173+
while items:
174+
current_probability, current_node= heapq.heappop(items)
175+
176+
if current_node== end_node:
177+
return-current_probability
178+
179+
if visited[current_node]:# added 3
180+
continue
181+
182+
visited[current_node]=True# added 2
183+
184+
for target_node, probabilityin node_to_pairs[current_node]:
185+
if visited[target_node]:# added 4
186+
continue
187+
188+
probability_=abs(current_probability)* probability
189+
190+
if probability_> max_probabilities[target_node]:
191+
max_probabilities[target_node]= probability_
192+
# It may cause the same `target_node` added into `items` more than once, but it doesn't matter. Because only the one `heappush`ed first may change the `max_probabilities` data.
193+
heapq.heappush(items, (-probability_, target_node))
194+
195+
return0
196+
```
197+
198+
##JavaScript
199+
```javascript
200+
// Welcome to create a PR to complete the code of this language, thanks!
201+
```
202+
203+
##Java
204+
```java
205+
// Welcome to create a PR to complete the code of this language, thanks!
206+
```
207+
208+
##C++
209+
```cpp
210+
// Welcome to create a PR to complete the code of this language, thanks!
211+
```
212+
213+
##C#
214+
```c#
215+
// Welcome to create a PR to complete the code of this language, thanks!
216+
```
217+
218+
##Go
219+
```go
220+
// Welcome to create a PR to complete the code of this language, thanks!
221+
```
222+
223+
##Ruby
224+
```ruby
225+
# Welcome to create a PR to complete the code of this language, thanks!
226+
```
227+
228+
##C, Kotlin, Swift, Rust or other languages
229+
```
230+
// Welcome to create a PR to complete the code of this language, thanks!
231+
```

‎images/examples/1514_1.png

6.25 KB
Loading

‎images/examples/1514_2.png

6.4 KB
Loading

‎images/examples/1514_3.png

4.62 KB
Loading

‎images/examples/743_1.png

7.38 KB
Loading
8.84 KB
Loading

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp