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:
- It can jump exactly
a
positions forward (to the right). - It can jump exactly
b
positions backward (to the left). - It cannot jump backward twice in a row.
- It cannot jump to any
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
- All the elements in
forbidden
are distinct. - Position
x
is not forbidden.
Related Topics:
Dynamic Programming, Breadth-first Search
// OJ: https://leetcode.com/problems/minimum-jumps-to-reach-home
// Author: github.com/lzl124631x
// Time: O()
// Space: O()
class Solution {
public:
int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
int g = __gcd(a,b);
if((x % g) != 0) {
return -1;
}
int vis[6001], ban[2001];
memset(vis, 0, sizeof(vis));
memset(ban, 0, sizeof(ban));
for(int v : forbidden) {
vis[v] = 1;
ban[v] = 1;
}
priority_queue<pair<int,int>, vector<pair<int, int>>, greater<pair<int,int>>> q;
q.emplace(0, 0);
while(q.size()) {
auto [steps, node] = q.top();
q.pop();
if(a >= b && node > x) {
continue;
}
if(node == x) {
return steps;
}
if(!vis[node]) {
vis[node] = 1;
if(node + a <= 6000 && !vis[node + a]) {
q.emplace(steps + 1, node + a);
}
if(node + a - b <= 6000 && node + a - b >= 0 && !vis[node + a - b] && !(node + a <= 2000 && ban[node + a])) {
q.emplace(steps + 2, node + a - b);
}
}
}
return -1;
}
};