题解 | #跳跃游戏(三)#

跳跃游戏(三)

http://www.nowcoder.com/practice/14abdfaf0ec4419cbc722decc709938b

题意

给一个数组,每个位置表示当前能到之后的数组的最远距离,求从最开始到最后一个的位置跳转的最小次数

限制:

数组长度不大于1000

方法

遍历枚举

直接模拟题目,增加一个辅助数组记录每个位置的最小跳次数.

从头开始遍历,对每个可以到达的位置,更新它和它之后的位置的最小跳跃次数

如果有位置能直接到终点,则直接输出即可

以题目的样例数据[2,1,3,3,0,0,100]为例

下标 操作 辅助数组
0 2 把它之后的两个位置赋值1 [0,1,1,INF,INF,INF,INF]
1 1 把它之后的一个位置赋值2,但是因为之后一个位置为1,小于2,所以不产生效果过 [0,1,1,INF,INF,INF,INF]
2 3 把它之后的3个位置赋值2 [0,1,1,2,2,2,INF]
3 3 直接能到终点直接输出3 -

代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return int整型
     */
    int minJumpStep(vector<int>& nums) {
        if(nums.size() == 1)return 0; // 特殊情况处理
        if(nums.size() == 0)return -1; // 特殊情况处理
        const int INF = 0x3f3f3f3f;
        vector<int> ans(nums.size(),INF); //初始化
        ans[0] = 0;
        for(int i = 0;i<nums.size();i++){
            if(ans[i]==INF)continue; // 不可达忽略
            if(i+nums[i] >= nums.size()-1){ // 直接跳到终点 输出
                return ans[i]+1;
            }
            for(int j = 1;j<=nums[i];j++){ // 注意只保存最小值
                ans[i+j] = min(ans[i+j],ans[i]+1);
            }
        }
        return -1;
    }
};

复杂度分析

时间复杂度: 对于每个位置,最坏情况更新几乎整个数组,所以时间复杂度为O(n2)O(n^2)

空间复杂度: 主要消耗在辅助数组的存储,所以空间复杂度为O(n)O(n)

基于数学性质的时间复杂度优化

注意到因为跳跃是从1到当前最大距离都会更新的,那么如果每次更新前,整个距离数组是单调递增的,那么每个数组更新后也是单调递增的

因为更新的值大于当前位置的值,且更新当前位置之后位置的值. 上一次更新的值一定不大于这次更新的值,同时更新时为了维护最小的次数,所以每个位置最多被更新一次

根据单调性,可以从后向前更新

代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return int整型
     */
    int minJumpStep(vector<int>& nums) {
        if(nums.size() == 1)return 0; // 特殊情况处理
        if(nums.size() == 0)return -1; // 特殊情况处理
        const int INF = 0x3f3f3f3f;
        vector<int> ans(nums.size(),INF); //初始化
        ans[0] = 0;
        for(int i = 0;i<nums.size();i++){
            if(ans[i]==INF)continue;
            if(i+nums[i] >= nums.size()-1){
                return ans[i]+1;
            }
            for(int j = nums[i];j>=1;j--){ // 从后向前
                if(ans[i+j]!=INF)break; // 唯一一次被更新
                ans[i+j] = ans[i]+1;
            }
        }
        return -1;
    }
};

复杂度分析

时间复杂度: 这样控制顺序以后,每个位置至多被更新一次,所以时间复杂度为O(n)O(n)

空间复杂度: 主要消耗在辅助数组的存储,所以空间复杂度为O(n)O(n)

全部评论

相关推荐

昨天 08:58
已编辑
门头沟学院 Java
ttl:&nbsp;3.19一面晚上过3.20二面3.23oc3.25offerbase:末9有一段中小厂实习一面面经:(总体时长一个小时二十分钟左右没什么八股,主要都是问项目和场景题1.实习(问了有四十分钟,感觉面试官很看重实习这一块,一直在拷打,问到后面我都要疯了,好在准备得比较充分1️⃣用的是什么中间件,有参与技术选型吗,实习的项目里为什么选这个RabbitMQ而不是kafka,为什么不用RocketMQ,为什么放弃异步,自己的项目里面使用的是kafka,那你觉得项目和实习的中间件选型有差异的原因是什么,他们之间的区别在哪里,底层的原因知道吗(高柱到这里已经快疯了,但是硬着头皮答完了,主要是从一致性吞吐量和框架的契合度答,面试官说答得挺好的,应该是没什么问题,这一块就问了快半个小时,到这里我已经快疯了2️⃣项目怎么对接上下游3️⃣介绍项目的难点重点4️⃣微服务(高柱实习是单体项目没涉及这一块5️⃣Redis的使用2.项目:1️⃣智能客服是怎么应用在项目里的(langchain4j➕rag➕functioncalling)2️⃣RAG了解多少3️⃣文本向量化的难点是什么,了解哪些大模型的知识(我一点不懂,纯瞎扯,但貌似扯对了4️⃣对ai的态度是什么,aicoding相关5️⃣怎么保证多节点下Caffeine缓存里面数据都是一致的(答的是短ttl,面试官不是很满意,但是我确实不太懂这个怎么保证,后来查了还是不懂怎么保证6️⃣Redis的使用,和你的实习项目的使用有区别吗,还有一些引申问题3.八股(含量不高,就是走个过场1️⃣进程的内存布局2️⃣Redis三剑客3️⃣微服务相关知识(高柱已经忘得差不多了…勉强答上来4️⃣JVM5️⃣线程状态6️⃣线程安全,在你的实习项目里怎么保证线程安全的(又绕回来了4.智商题找异常球5.手撕:1️⃣五道sql,不难2️⃣力扣不重叠的滑动窗口数组,贪心➕双指针秒了强度拉满了这个一面,高柱到后面人都是傻的二面面经:(就半个小时实习拷打,简历上写了几点就问了几点,问完就结束了,无手撕
查看19道真题和解析
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务