题目

给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
假设你总是可以到达数组的最后一个位置。

示例:
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置

思路 - O(n^2)

这种从起点到终点的题目,算最小操作次数的,可以考虑从终点往起点走(反向查找),看每一步最远能走多远 (贪心)

  1. class Solution {
  2. public int jump(int[] nums) {
  3. int step = 0; // 跳跃次数
  4. int curPosition = nums.length - 1; // 从终点往起点走
  5. while (curPosition > 0) { // 循环直到到达起点
  6. for (int i = 0; i < curPosition; i++) { // 从左到右,找到最左边的能跳到当前位置的点
  7. if (i + nums[i] >= curPosition) { // 从i起跳能跳到当前位置
  8. curPosition = i; // 更新当前位置为i
  9. step++;
  10. break;
  11. }
  12. }
  13. }
  14. return step;
  15. }
  16. }

思路 - O(n)

jumpPos是当前能到的最远的位置,如果到了这个位置,也就是 i == jumpPos,说明需要跳了,也就是step++。
maxPos是遍历nums[i, nums[i] + i]之后,能到的最远位置,需要跳的时候,就是跳到这个最远位置 (贪心)

  1. class Solution {
  2. public int jump(int[] nums) {
  3. int step = 0; // 结果
  4. int jumpPos = 0; // 在这个位置上说明需要跳了
  5. int maxPos = 0; // 目前最远可以到的位置
  6. for (int i = 0; i < nums.length - 1; i++) {
  7. maxPos = Math.max(maxPos, i + nums[i]); // 更新目前可跳最远位置
  8. if (i == jumpPos) { // 已经到了能到的最远位置,此时需要跳了
  9. step++; // 跳
  10. jumpPos = maxPos; // 跳完之后,更新能走到的最远位置,下次到达这个位置,就要跳
  11. }
  12. }
  13. return step;
  14. }
  15. }