贪心算法之最少跳跃步数(C++)

未来,未来。

------2024年6月17日


题目描述

给定一个含n(1≤n≤1000)个非负整数数组nums(0≤numsi≤1000),数组中的每个元素表示在该位置可以跳跃的最大长度,假设总是可以从初始位置0到达最后一个位置n-1,设计一个算法求最少的跳跃次数。

例如nums={2,3,1,1,4},n=5,从位置0可以跳一步到达位置1,再从位置1跳3步到位置4,所以结果为2。

题解思路

贪心法

  1. 当n=1时,不需要跳跃,跳跃步数为0;

  2. 当n>1时,用steps表示跳跃步数;

错误思路:

  • 在i=0时会跳出第一步,那它能达到最远的位置就是end=i+numsi,那是不是说每次都跳跃最远的距离(即numsi)就能跳跃最少的步数呢?答案是否定的,那题目的例子来说:
  • 此时nums0=2,能跳跃的最远距离是2,能达到的最远位置是0+nums0=2,到达2号位;
  • 此时nums2=1,能跳跃的最远距离就是1,能达到的最远位置是2+nums2=3,到达3号位;
  • 此时nums3=1,能跳跃的最远距离就是1,能达到的最远位置是3+nums3=4,到达4号位;
  • 可以看到一共跳跃了3步,而它明明只需要两步就能到达最后的位置。

正确思路:多考虑一步,既要考虑当前跳跃能达到的最远位置,还需要考虑从i到最远位置之间的numsk(k∈i, i+nums\[i])能达到的最远位置k+numsk,即使它最终超过了nums.size()-1。

再举个例子

当前nums\[\] = {2,1,3,2,2,1,4} ,pos的位置变化从0→2→4→末尾(甚至超过末尾),只需要三步即可。


注:可以好好体会一下这个思路,考试周结束我会继续完善这篇博客。

代码实现

cpp 复制代码
// 提前向前看两个位置, 找到最远跳跃距离
int minStep(vector<int> &num){
    int len = num.size();
    int ans = 0;
    if(len == 1){
        return 0;
    }
    for(int i = 0; i < len; ){
        int maxstep1 = i + num[i];//记录当前能达到的最远位置
        int maxstep2;
        int max = 0;
        int pos = 0;
        for(int j = i + 1; j <= i + num[i] && j < len; j++){
            //在该区间中找第二个能达到的最远位置对应的j

            maxstep2 = j + num[j];//记录j能达到的最远位置
            if(maxstep2 > max){
                max = maxstep2;
                pos = j;
            }
            if(maxstep2 >= len - 1){
                break;//如果已经超过len-1,说明已经能跳出最后一个位置了,那么就不需要找j了
            }
        }
        cout<<"从"<<i<<"位置跳跃到"<<pos<<"位置"<<endl;
        ans++;
        if(maxstep2 >= len - 1){
            cout<<"从"<<pos<<"位置跳跃到末尾"<<endl;
            ans++;
            break;
        }
        i = pos;//更新i作为下一次的起点
    }
    return ans;
}

代码简化

cpp 复制代码
int minStep(vector<int> &v){
    int len = v.size();
    int maxDistance = 0;
    int end = 0;
    int steps = 0;
    // 最后一个位置不需要向前跳跃了哦
    for(int i = 0; i < len - 1; i++){
        maxDistance = max(maxDistance, v[i] + i);
        if(i == end){//说明能走到最远的位置,那么后面仍然有数字
            end = maxDistance;
            steps++;
        }
    }
    return steps;
}

运行结果

相关推荐
晴天的雨.992几秒前
类和对象下(内部类,匿名对象,对象拷贝时的编译器优化)
开发语言·c++·算法
旖旎夜光20 分钟前
LeetCode 238:除自身以外数组的乘积(前缀和) —— 题解
数据结构·c++·算法·leetcode·前缀和
一条大祥脚26 分钟前
26杭电暑期第八场(后半)快读|快写|tarjan|路径DP|mex转化|扫描线|前缀和|二分图
数据结构·算法·tarjan·杭电多校·强联通分量·动态规划dp
奈斯先生Vector30 分钟前
从“能调用”到“可运营”:AI Agent 进入多模型时代后的架构升级
java·javascript·数据库·人工智能·算法·架构·aigc
2601_9561219741 分钟前
Bellman-ford算法
算法
叠层归一研究院1 小时前
基于区分本源的此刻存在唯一性本体论推演
人工智能·算法
luj_17681 小时前
尾椎藏今生记忆?骨盆对应不确定性
开发语言·网络·c++·经验分享·算法
深圳多奥智能一卡(码、脸)通系统1 小时前
智能梯控SDK可直接用于第三方开发对接的接口文档说明书
服务器·前端·算法
裕晟资质规划10 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法