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

未来,未来。

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


题目描述

给定一个含n(1≤n≤1000)个非负整数数组nums(0≤nums[i]≤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+nums[i],那是不是说每次都跳跃最远的距离(即nums[i])就能跳跃最少的步数呢?答案是否定的,那题目的例子来说:
  • 此时nums[0]=2,能跳跃的最远距离是2,能达到的最远位置是0+nums[0]=2,到达2号位;
  • 此时nums[2]=1,能跳跃的最远距离就是1,能达到的最远位置是2+nums[2]=3,到达3号位;
  • 此时nums[3]=1,能跳跃的最远距离就是1,能达到的最远位置是3+nums[3]=4,到达4号位;
  • 可以看到一共跳跃了3步,而它明明只需要两步就能到达最后的位置。

正确思路:多考虑一步,既要考虑当前跳跃能达到的最远位置,还需要考虑从i到最远位置之间的nums[k](k∈[i, i+nums[i]])能达到的最远位置k+nums[k],即使它最终超过了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;
}

运行结果

相关推荐
金融小师妹3 小时前
应用BERT-GCN跨模态情绪分析:贸易缓和与金价波动的AI归因
大数据·人工智能·算法
广州智造3 小时前
OptiStruct实例:3D实体转子分析
数据库·人工智能·算法·机器学习·数学建模·3d·性能优化
Trent19855 小时前
影楼精修-肤色统一算法解析
图像处理·人工智能·算法·计算机视觉
feifeigo1235 小时前
高光谱遥感图像处理之数据分类的fcm算法
图像处理·算法·分类
北上ing6 小时前
算法练习:19.JZ29 顺时针打印矩阵
算法·leetcode·矩阵
.格子衫.7 小时前
真题卷001——算法备赛
算法
XiaoyaoCarter7 小时前
每日一道leetcode
c++·算法·leetcode·职场和发展·二分查找·深度优先·前缀树
Hygge-star7 小时前
【数据结构】二分查找5.12
java·数据结构·程序人生·算法·学习方法
June`9 小时前
专题二:二叉树的深度搜索(二叉树剪枝)
c++·算法·深度优先·剪枝
好吃的肘子10 小时前
Elasticsearch架构原理
开发语言·算法·elasticsearch·架构·jenkins