A certain bug's home is on the x-axis at position x
. Help them get there from position 0
.
The bug jumps according to the following rules:
a
positions forward (to the right).b
positions backward (to the left).forbidden
positions.The bug may jump forward beyond its home, but it cannot jump to positions numbered with negative integers.
Given an array of integers forbidden
, where forbidden[i]
means that the bug cannot jump to the position forbidden[i]
, and integers a
, b
, and x
, return the minimum number of jumps needed for the bug to reach its home. If there is no possible sequence of jumps that lands the bug on position x
, return -1.
Example 1:
Input: forbidden = [14,4,18,1,15], a = 3, b = 15, x = 9 Output: 3 Explanation: 3 jumps forward (0 -> 3 -> 6 -> 9) will get the bug home.
Example 2:
Input: forbidden = [8,3,16,6,12,20], a = 15, b = 13, x = 11 Output: -1
Example 3:
Input: forbidden = [1,6,2,14,5,17,4], a = 16, b = 9, x = 7 Output: 2 Explanation: One jump forward (0 -> 16) then one jump backward (16 -> 7) will get the bug home.
Constraints:
1 <= forbidden.length <= 1000
1 <= a, b, forbidden[i] <= 2000
0 <= x <= 2000
forbidden
are distinct.x
is not forbidden.This problem asks for the minimum number of jumps a bug needs to reach its home at position x
, starting from position 0. The bug can jump a
units forward, b
units backward (but not two backward jumps consecutively), and cannot land on any forbidden positions listed in forbidden
.
The optimal approach is Breadth-First Search (BFS). BFS guarantees finding the shortest path in an unweighted graph (like this one where each jump is a single edge).
Algorithm:
State Representation: We represent the bug's state as a tuple (position, direction)
, where position
is the bug's current location, and direction
is 1 (forward) or 0 (backward). The direction helps enforce the "no consecutive backward jumps" rule.
Queue and Visited Set: A queue q
stores states to explore, starting with (0, 1)
. A set vis
tracks visited states to avoid cycles. The maximum position to consider is 6000, as explained below.
BFS Iteration: The main loop repeatedly dequeues states from q
.
Jump Actions: For each state:
x
. If so, it returns the number of steps taken (the BFS level).position + a
, 1).position - b
, 0).Validity Check: Each next state is checked for validity:
[0, 6000)
(explanation below).forbidden
.Queueing and Visiting: If a next state is valid, it's added to q
and marked as visited.
Failure Condition: If q
becomes empty before finding x
, there's no solution, and -1 is returned.
Why the upper bound is 6000:
The maximum reachable position is constrained. If a >= b
, the furthest the bug can go is x + b
because further forward jumps won't be helpful in reaching x
. If a < b
, a more complex analysis is needed, but a value of 6000 is sufficient as an upper bound in this problem's constraints (max position and max jump lengths).
Time Complexity: O(M), where M is the upper bound (6000 in this case). In the worst case, we might visit all possible states within the bounds.
Space Complexity: O(M), due to the queue and visited set, which can store up to M states.
Code (Python):
from collections import deque
def minimumJumps(forbidden, a, b, x):
s = set(forbidden)
q = deque([(0, 1)])
vis = {(0, 1)}
ans = 0
while q:
for _ in range(len(q)):
i, k = q.popleft()
if i == x:
return ans
nxt = [(i + a, 1)]
if k == 1:
nxt.append((i - b, 0))
for j, k in nxt:
if 0 <= j < 6000 and j not in s and (j, k) not in vis:
q.append((j, k))
vis.add((j, k))
ans += 1
return -1
The code in other languages (Java, C++, Go, TypeScript) follows the same algorithm and logic, differing only in syntax and data structure implementations. They all achieve the same time and space complexity.