45. Jump Game II(跳跃游戏II)

问题描述
Given an array of non-negative integers, you are initially positioned at the first index of the array.
Each element in the array represents your maximum jump length at that position.
Your goal is to reach the last index in the minimum number of jumps.
For example:
Given array A = [2,3,1,1,4]
The minimum number of jumps to reach the last index is 2. (Jump 1 step from index 0 to 1, then 3 steps to the last index.)

问题分析
这个问题的要求很明确,给定一串数字,数字的值表示在这个位置可以直接到达的最大长度,我们要求的则是到达最后一个数字所需要的最小步数,问题看起来很简单,但是从数字开头到结尾可能有许多种不同的走法,我们怎么找出最短的那条路径呢?我们可以用一个变量step来记录我们所走的步数,但是step什么时候才要加1呢?我们可以采取这样的思维,我们可以定义i从0到最后一个下标,i是依次加1递增的,但是这其中必然有很多不必要走的步数,我们的step只在必须要走的步数才加1。我们可以定义lastable,currentable两个变量。lastable表示从上一个记录的位置可以到达的最大位置,如果i的值不大于该数值,则表示从last这个位置可以直接到达i的位置,step就不需要加1;如果i的值大于该数值,则表示从last到大不了该位置,这一步就是必须的,step就要加1。同时要更新laetble的值。而currentable记录当前位置可以到达的最大位置,用以更新lastable的值。

代码展示

#include <iostream>
#include <stdlib.h>
#include <vector>
using namespace std; 

class Solution {
public:
    int jump(vector<int>& nums){
        int lastable=0, currentable = 0, step =0;
        int n=nums.size();
        for(int i=0;i<n;i++){
            if(i>lastable){              //如果下标i超过了上一次最大可以到的的位置,则步数就要加1 
                step+=1;
                lastable = currentable;   //并且要重新定义上一步可以达到的最大位置 
            }
            int a= nums[i]+i;             //如果下标i没有超过上一次可以达到的最大位置,则代表这一位置可以有上一个记录的位置直接跳达 
            if(currentable<a){
                currentable = a;           //所以到这个位置步数可以省略,既不用加1 ,并且每次都要记录此位置可以到达的最大位置 
            }
        }
        return currentable >= n - 1 ? step : 0;    //如果最后可以到达,则返回所用步数。 
    }
};

int main(){
    int n;
    vector<int> nums;
    cout<<"输入容器的长度:";
    cin>>n;
    int num[n];
    for(int i = 0;i<n;i++){
        cin>>num[i];
        nums.push_back(num[i]);
    }
    Solution solution;
    int result=solution.jump(nums);
    cout<<result<<endl;
}

运行结果展示
这里写图片描述

<think>好的,用户需要查找LeetCode上跳跃问题的C++解决方案。首先,我得明确用户具体指的是哪一个跳跃问题。因为LeetCode上有几个类似的题目,比如“跳跃游戏”(Jump Game)和“跳跃游戏II”(Jump Game II)。根据用户提到的动态规划问题,以及引用[1]中的描述,应该是“跳跃游戏”,也就是判断能否到达最后一个位置的问题。 接下来,我需要回顾这个问题的解决方法。根据常见的解法,通常有贪心算法和动态规划两种方法。动态规划可能会比较直观,但时间复杂度较高;而贪心算法更高效,可以在O(n)时间内解决问题。用户可能更希望看到最优的解法,所以优先考虑贪心算法。 然后,我需要确认用户需要的是C++的实现。引用[2]中提供了一个C++的数组旋转例子,这可以作为代码风格的参考。因此,在编写代码时,应保持类似的风格,使用vector,包含必要的头文件,并给出一个类或者函数的实现。 现在,需要构建解决方案的步骤。对于跳跃游戏问题,贪心算法的核心是维护一个最远可达的位置,遍历数组时更新这个值。如果当前位置超过了最远可达位置,说明无法到达终点。否则,在遍历结束后判断最远可达位置是否大于等于终点索引。 接下来,需要将这一思路转化为C++代码。确保代码结构清晰,注释到位,便于用户理解。同时,按照引用[2]中的示例,可能使用类Solution,并在其中定义成员函数canJump。测试用例部分也需要简单展示如何使用这个函数。 另外,用户可能对算法的时间复杂度和空间复杂度感兴趣,所以需要补充这部分的分析。贪心算法的时间复杂度是O(n),空间复杂度是O(1),这是最优的解决方案。 最后,生成相关问题,帮助用户进一步学习。可能需要包括动态规划与贪心的对比、跳跃游戏II的解法、优化方法等。确保问题相关且有引导性,促进用户深入探索。 检查LaTeX格式是否符合要求,数学表达式是否正确使用$...$。例如,数组索引i,最远位置max_reach等不需要数学格式,但如果有方程或复杂表达式则需处理。当前问题中可能不需要太多数学公式,但如果有的话,如max_reach的更新规则,可以用$max\_reach = \max(max\_reach, i + nums[i])$。 总结整个思考过程,确保回答结构清晰,代码正确,引用正确添加,并生成相关问题。</think>关于LeetCode跳跃游戏问题的C++解决方案,以下是详细实现与分析: ### 问题描述 给定非负整数数组$nums$,每个元素表示在当前位置能跳跃的最大长度。判断从第一个位置出发,能否到达最后一个位置(索引$n-1$)。 ### 贪心算法实现(最优解) 这是时间复杂度$O(n)$、空间复杂度$O(1)$的高效解法: ```cpp #include <vector> using namespace std; class Solution { public: bool canJump(vector<int>& nums) { int max_reach = 0; // 当前能到达的最远位置 for (int i = 0; i < nums.size(); ++i) { if (i > max_reach) return false; // 当前位置不可达 max_reach = max(max_reach, i + nums[i]); if (max_reach >= nums.size() - 1) return true; // 提前终止条件 } return true; } }; ``` ### 算法解析 1. **核心思想**:维护当前能到达的最远位置$max\_reach$ 2. **终止条件**: - 当遍历到$i > max\_reach$时说明存在无法跨越的缺口 - 当$max\_reach \geq n-1$时提前返回成功 3. **正确性证明**:通过不断扩展可达范围,最终覆盖终点即成功[^1] ### 动态规划解法对比 虽然贪心算法更优,但动态规划解法有助于理解问题本质: ```cpp bool canJump_DP(vector<int>& nums) { vector<bool> dp(nums.size(), false); dp[0] = true; for (int i = 0; i < nums.size(); ++i) { if (!dp[i]) continue; for (int j = 1; j <= nums[i] && i+j < nums.size(); ++j) dp[i+j] = true; } return dp.back(); } ``` 时间复杂度$O(n^2)$,空间复杂度$O(n)$,适用于教学演示但实际效率较低[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值