「贪心」地进行正向查找,每次找到可到达的最远位置,就可以在线性时间内得到最少的跳跃次数。
#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")