Skip to content

Commit 4bf5b80

Browse files
committed
AlgoExpert Min Number Of Jumps
1 parent d3a4c1f commit 4bf5b80

File tree

2 files changed

+93
-0
lines changed

2 files changed

+93
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,7 @@ First column links to the problem in AlgoExpert, second is the problem's difficu
11101110
| [Min Height BST][ae&min-height-bst] | 🟠 Medium | [![python](res/py.png)][ae&min-height-bst#py] |
11111111
| [Min Max Stack Construction][ae&min-max-stack-construction] | 🟠 Medium | [![python](res/py.png)][ae&min-max-stack-construction#py] |
11121112
| [Min Number Of Coins For Change][ae&min-number-of-coins-for-change] | 🟠 Medium | [![python](res/py.png)][ae&min-number-of-coins-for-change#py] |
1113+
| [Min Number Of Jumps][ae&min-number-of-jumps] | 🔴 Hard | [![python](res/py.png)][ae&min-number-of-jumps#py] |
11131114
| [Minimum Characters For Words][ae&minimum-characters-for-words] | 🟠 Medium | [![python](res/py.png)][ae&minimum-characters-for-words#py] |
11141115
| [Minimum Waiting Time][ae&minimum-waiting-time] | 🟢 Easy | [![python](res/py.png)][ae&minimum-waiting-time#py] |
11151116
| [Monotonic Array][ae&monotonic-array] | 🟠 Medium | [![python](res/py.png)][ae&monotonic-array#py] |
@@ -1179,6 +1180,8 @@ First column links to the problem in AlgoExpert, second is the problem's difficu
11791180
[ae&min-max-stack-construction#py]: algoexpert/min-max-stack-construction.py
11801181
[ae&min-number-of-coins-for-change]: https://www.algoexpert.io/questions/min-number-of-coins-for-change
11811182
[ae&min-number-of-coins-for-change#py]: algoexpert/min-number-of-coins-for-change.py
1183+
[ae&min-number-of-jumps]: https://www.algoexpert.io/questions/min-number-of-jumps
1184+
[ae&min-number-of-jumps#py]: algoexpert/min-number-of-jumps.py
11821185
[ae&minimum-characters-for-words]: https://www.algoexpert.io/questions/minimum-characters-for-words
11831186
[ae&minimum-characters-for-words#py]: algoexpert/minimum-characters-for-words.py
11841187
[ae&minimum-waiting-time]: https://www.algoexpert.io/questions/minimum-waiting-time

algoexpert/min-number-of-jumps.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Min Number Of Jumps
2+
# 🔴 Hard
3+
#
4+
# https://www.algoexpert.io/questions/min-number-of-jumps
5+
#
6+
# Tags: Array - Dynamic Programming
7+
8+
import timeit
9+
10+
11+
# Use nested loops and an extra array of number of jumps required to
12+
# reach a position. Visit all the indexes, and use the values in them to
13+
# update the number of jumps required to reach all the positions that
14+
# can be reached from the current index.
15+
#
16+
# Time complexity: O(n^2) - From each index we could end up visiting all
17+
# other indexes.
18+
# Space complexity: O(n) - We use len(array) worth of extra memory.
19+
class BruteForce:
20+
def minNumberOfJumps(self, array):
21+
jumps = [float("inf")] * len(array)
22+
jumps[0] = 0
23+
for i in range(len(array)):
24+
for j in range(array[i]):
25+
idx = i + j + 1
26+
if i + j + 1 < len(array):
27+
jumps[idx] = min(jumps[i] + 1, jumps[idx])
28+
return jumps[-1]
29+
30+
31+
# Store only the maximum position we can reach at a given point, the
32+
# number of steps we can take without making another jump and the number
33+
# of jumps that we have taken already.
34+
#
35+
# Time complexity: O(n) - We visit each position once and do O(1) work.
36+
# Space complexity: O(1) - We use constant extra memory.
37+
class DP:
38+
def minNumberOfJumps(self, array):
39+
if len(array) == 1:
40+
return 0
41+
# Visit the first position, consuming one jump to move out.
42+
max_reach, steps_left, jumps = array[0], array[0], 1
43+
# We already "visited" the first position and we are trying to
44+
# reach the last position on the array, not the "position"
45+
# immediately after the array, iterate from i to len(array) - 1
46+
for i, val in enumerate(array[1:-1]):
47+
# Consume one step to get here.
48+
steps_left -= 1
49+
# The maximum index we can reach from this position.
50+
max_reach = max(max_reach, val + i)
51+
# If we have consumed all steps.
52+
if not steps_left:
53+
# We are forced to take a jump.
54+
jumps += 1
55+
# We are taking a jump, update the number of steps that
56+
# we have left until forced to take the next jump.
57+
steps_left = max_reach - i
58+
return jumps
59+
60+
61+
def test():
62+
executors = [
63+
BruteForce,
64+
DP,
65+
]
66+
tests = [
67+
[[1], 0],
68+
[[1, 1], 1],
69+
[[1, 1, 1], 2],
70+
[[3, 4, 2, 1, 2, 3, 7, 1, 1, 1, 3], 4],
71+
]
72+
for executor in executors:
73+
start = timeit.default_timer()
74+
for _ in range(1):
75+
for col, t in enumerate(tests):
76+
sol = executor()
77+
result = sol.minNumberOfJumps(t[0])
78+
exp = t[1]
79+
assert result == exp, (
80+
f"\033[93m» {result} <> {exp}\033[91m for"
81+
+ f" test {col} using \033[1m{executor.__name__}"
82+
)
83+
stop = timeit.default_timer()
84+
used = str(round(stop - start, 5))
85+
cols = "{0:20}{1:10}{2:10}"
86+
res = cols.format(executor.__name__, used, "seconds")
87+
print(f"\033[92m» {res}\033[0m")
88+
89+
90+
test()

0 commit comments

Comments
 (0)