「贪心」地进行正向查找,每次找到可到达的最远位置,就可以在线性时间内得到最少的跳跃次数。
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int nums[N];
int n;
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &nums[i]);
}
//初始化最远位置标记far
int far = nums[0];
int ans = 1;
if (n == 1)
printf("0");
else {
for (int i = 0; i < n; i++) {
int tmpi = i;
int tmp = 0;
// 在(i,far] 中找能到达的最远位置
for (int j = i + 1; j <= far; j++) {
if (nums[j] + j > tmp) {
tmp = nums[j] + j;
tmpi = j;
}
}
//在范围内没找到,说明到达不到最后,跳出循环
if (tmpi == i) {
break;
} else // 次数加1
ans ++;
far = tmp; // 更新最远位置
if (far >= n - 1)// 如果最远位置 可以到达最后的位置,跳出循环
break;
i = tmpi - 1; // 最后更新下次循环的起始位置,i=tmpi-1,for里面还有+1,所以下一次的遍历起始位置是tmpi,就是本次找到的最远位置的起跳位置
}
if (far >= n - 1)
printf("%d", ans);
else
printf("-1");
}
return 0;
}
// 64 位输出请用 printf("%lld")

京公网安备 11010502036488号