力扣第55题 跳跃游戏

前言

记录一下刷题历程 力扣第55题 跳跃游戏


跳跃游戏

原题目:给你一个非负整数数组 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 , 所以永远不可能到达最后一个下标。

分析

我们使用贪心算法,target为索引。我们从倒数第二个位置开始遍历,位置3最大可以跳1步,可以跳到最后一个索引,此时把目标索引target更新为3,当前只要能从0跳到位置3就说明可以从位置0跳到最后一个位置即索引4。我们继续往前遍历,遍历到索引2,从位置2最多可以跳1步,因为从2到3可达,那么我们继续更新索引为2。然后继续遍历到位置1,从1最多可以跳3步,可以直接跳到最后一个索引,而且从位置1到位置2也是可达的,我们继续更新索引为1。我们继续向前遍历到位置0,位置0最多可以跳两步,说明0到1也是可达的,更新索引target为0。当我们逆序遍历完数组target为0时,就说明从0到最后一个位置是可达的。可以根据下面的图来理解:在这里插入图片描述

代码如下:

class Solution {
public:
    bool canJump(vector<int>& nums) {
        int target = nums.size() - 1; // 初始化目标位置为数组最后一个位置
        
        // 从倒数第二个位置向前遍历数组
        for (int i = nums.size() - 2; i >= 0; i--) {
            // 如果当前位置 i 可以跳跃至目标位置 target 或更远
            if (i + nums[i] >= target) {
                target = i; // 更新目标位置为当前位置 i
            }
        }
        
        // 如果最终目标位置为数组起始位置 0,则说明可以到达最后一个位置,返回 true
        // 否则返回 false
        return target == 0;
    }
};

解释注释

1.目标位置初始化:

int target = nums.size() - 1;
target 初始化为数组 nums 的最后一个位置,表示起始时希望能够直接跳到数组的最后一个位置。

2.倒序遍历数组:

for (int i = nums.size() - 2; i >= 0; i–) {
从数组倒数第二个位置开始向前遍历,因为最后一个位置不需要再判断。

3.更新目标位置:

if (i + nums[i] >= target) {
target = i;
}
如果当前位置 i 能够跳跃至目标位置 target 或更远(即 i + nums[i] >= target),则更新 target 为当前位置 i。
这里的逻辑是通过贪心算法,每次尽可能更新可以到达的最远位置。

4.判断是否可以到达:

return target == 0;
最终判断 target 是否等于数组的起始位置 0。如果等于,则表示可以从起始位置开始到达最后一个位置,返回 true。
否则,返回 false,表示无法从起始位置开始到达最后一个位置。

时间复杂度

时间复杂度: O(n),其中 n 是数组 nums 的长度。只需要单次遍历数组,因此时间复杂度是线性的。

  • 11
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值