力扣 —— 跳跃游戏

题目一(中等)

给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false

示例 1:

输入:nums = [2,3,1,1,4]

输出:true

解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。

示例 2:

输入:nums = [3,2,1,0,4]

输出:false

解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。

提示:

  • 1 <= prices.length <= 10^5^
  • 0 <= prices[i] <= 10^4^

题目思路

从终点向前遍历,一开始的 target 设置为 n - 1, 遍历指针 i 设置为 n - 2,当 i 遍历过起点(index 为 0)后遍历结束。if (i + nums[i] >= target) target = i 这个判断的含义是,如果从当前位置跳跃最大长度可以到达此时的 target,那么我们就把 target 更新为此时的 i (因为如果到达此时的 i , 就可以到达原本的 target,如此循环,一定可以到达一开始的 target 也就是最后一个下标 n - 1),然后 i-- 向前遍历,重复这个过程直到循环结束。 最后判断 if target == 0 ,说明从起始点开始一定有一个策略可以一直跳到最后一个下标,返回 true,否则说明不存在这样的策略,返回 false,游戏结束。

答案

java 复制代码
class Solution {
    public boolean canJump(int[] nums) {
        int target = nums.length -1;
        int i = target -1; 
        while(i >= 0){
            if(i + nums[i] >= target){
                target = i;
            }
            i--;
        }
        return target == 0 ; 
    }
}

题目二(中等)

给定一个长度为 n0 索引 整数数组 nums。初始位置为 nums[0]

每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i + j] 处:

  • 0 <= j <= nums[i]
  • i + j < n

返回到达 nums[n - 1] 的最小跳跃次数。生成的测试用例可以到达 nums[n - 1]

示例 1:

输入: nums = [2,3,1,1,4]

输出: 2

解释: 跳到最后一个位置的最小跳跃数是 2。

从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。

示例 2:

输入: nums = [2,3,0,1,4]

输出: 2

提示:

  • 1 <= prices.length <= 10^5^
  • 0 <= prices[i] <= 10^4^
  • 题目保证可以到达 nums[n-1]

题目思路

贪心的思路,局部最优:当前可移动距离尽可能多走,如果还没到终点,步数再加一。整体最优:一步尽可能多走,从而达到最小步数。要从覆盖范围出发,不管怎么跳,覆盖范围内一定是可以跳到的,以最小的步数增加覆盖范围,覆盖范围一旦覆盖了终点,得到的就是最小步数!

答案

java 复制代码
class Solution {
    public int jump(int[] nums) {
          if (nums == null || nums.length == 0 || nums.length == 1) {
            return 0;
        }
        //记录跳跃的次数
        int count=0;
        //当前的覆盖最大区域
        int curDistance = 0;
        //最大的覆盖区域
        int maxDistance = 0;
        for (int i = 0; i < nums.length; i++) {
            //在可覆盖区域内更新最大的覆盖区域
            maxDistance = Math.max(maxDistance,i+nums[i]);
            //说明当前一步,再跳一步就到达了末尾
            if (maxDistance>=nums.length-1){
                count++;
                break;
            }
            //走到当前覆盖的最大区域时,更新下一步可达的最大区域
            if (i==curDistance){
                curDistance = maxDistance;
                count++;
            }
        }
        return count;
    }
}
相关推荐
咒法师无翅鱼24 分钟前
【定理证明工具调研】Coq, Isabelle and Lean.
算法
风清云淡_A1 小时前
【java基础系列】实现数字的首位交换算法
java·算法
涵涵子RUSH1 小时前
合并K个升序链表(最优解)
算法·leetcode
爱吃西瓜的小菜鸡1 小时前
【C语言】矩阵乘法
c语言·学习·算法
l138494274511 小时前
Java每日一题(2)
java·开发语言·游戏
清炒孔心菜1 小时前
每日一题 338. 比特位计数
leetcode
sjsjs112 小时前
【多维DP】力扣3122. 使矩阵满足条件的最少操作次数
算法·leetcode·矩阵
哲学之窗2 小时前
齐次矩阵包含平移和旋转
线性代数·算法·矩阵
Sudo_Wang3 小时前
力扣150题
算法·leetcode·职场和发展
qystca3 小时前
洛谷 P1595 信封问题 C语言dp
算法