题意:
有一只跳蚤的家在数轴上的位置 x
处。请你帮助它从位置 0
出发,到达它的家。
跳蚤跳跃的规则如下:
- 它可以 往前 跳恰好
a
个位置(即往右跳)。 - 它可以 往后 跳恰好
b
个位置(即往左跳)。 - 它不能 连续 往后跳
2
次。 - 它不能跳到任何
forbidden
数组中的位置。
跳蚤可以往前跳 超过 它的家的位置,但是它 不能跳到负整数 的位置。
给你一个整数数组 forbidden
,其中 forbidden[i]
是跳蚤不能跳到的位置,同时给你整数 a
, b
和 x
,请你返回跳蚤到家的最少跳跃次数。如果没有恰好到达 x
的可行方案,请你返回 -1
。
解题思路:
宽度优先搜索,BFS
设置一个数组,来判断当前的位置是否可以走
队列类型定义为pair类型,first表示可以走到哪里,second表示能否向后跳,如果当前位置是后跳过的,因为不能连续跳两次,那么就不能往后跳
右边界设置为6000,防止无限向前跳
代码详解:
class Solution {
public:
int minimumJumps(vector<int>& forbidden, int a, int b, int x) {
int left = 0;
queue<pair<int, int>> q; // 队列中存pair,第一个表示可以跳的位置,第二个表示能否再往后跳
int c[8000];
memset(c, 0, sizeof(c));
for (int i = 0, n = forbidden.size(); i < n; i++) {
c[forbidden[i]] = 1; // 禁止跳
}
q.push({0, 0}); // 0 已经不能向后跳
int ans = 0;
while (q.size()) {
int len = q.size();
for (int j = 0; j < len; j++) {
pair<int, int> k = q.front();
q.pop();
if (k.first == x) { // 如果达到x,退出
return ans;
}
if (k.first - b > 0 && k.second == 1 && c[k.first - b] == 0) { // 如果k.second==1,表示他可以向前也可以向后,k.first-b == 0表示可以往后跳
c[k.first - b] = 1;
q.push({k.first - b, 0});
}
if (c[k.first + a] == 0 && k.first + a < 6000) { // 右边界
c[k.first + a] = 1;
q.push({k.first + a, 1});
}
}
ans++;
}
return -1;
}
};