LeetCode--45.跳跃游戏 II
前言:今天可是没有断更哦
解题思路:
1.获取信息:
给定一个长度为 n 的并且以0索引开头的整数数组,初始位置为nums[0]
每个元素nums[ i ]表示,从索引 i 向后可跳转的最大长度
意思就是说,你拼尽全力可以跳那么远,但是你也可以不用全力,也可以不跳
所以你跳跃的范围在 0 到 nums[ i ]之间,闭区间
要求返回到达 nums[ n-1 ]的最小跳跃次数
提示信息:题目保证可以到达nums[ n-1 ]
nums[ i ]的值可能会为0
2.分析题目:
这道题还蛮有意思的,蹦蹦跳跳的问题
我在碰到类似这样的蹦蹦跳跳的游戏的时候,我一般会在脑子里面模拟我跳跃的每一种情况
也就是把所有情况都走一遍就可以知道最小的跳跃次数了,这就是暴力法的雏形
我在后面对暴力法进行了优化,因为暴力法会在第74个示例的时候超时
另外根据提示信息和力扣的题解,我也了解了一种方法
每种方法的思路放在了尝试编写代码的环节,借着代码来帮助你理解
3.示例查验:
示例2:提醒了,nums[ i ]的值可能会为0
4.示例查验:
(1)暴力法:(会在第74个示例的时候超时)
思路我已经在分析题目环节时说过了,就不做过多阐述了
class Solution {
public:int jump(vector<int>& nums) {return GetRes(nums,0,nums.size(),0);}
private:int GetRes(vector<int>&nums,int i,int size,int index){if(i>=size-1)return index;if(nums[i]==0)return INT_MAX;int res=INT_MAX;for(int j=1;j<=nums[i];j++){res=min(res,GetRes(nums,i+j,size,index+1));}return res;}
};
(2)提前看一步(暴力法的优化):
优化思路:暴力法之所以会超时,就是因为把那些一看就不可能是最小跳跃数的情况也彻底执行了
所以,我在对选取跳跃距离的步骤上加了一个判断条件,我原本在的位置为 k ,如果我跳过去的那个位置为 i ,nums[ i ]的最大长度为 j ,确保 j + ( i - k )是最长的,那么这种情况就是一个优先的选择
说实话,我觉得这个优化能过全是这道题目其实并不严苛,因为我这相当于只是提前模拟了一步,就像围棋中我在脑子里面在我原有的一步中模拟了下一步可能的结果
模拟的下一步可能只是对于当前信息来说是有利的,但是长远来看,可能就误入歧途了
所以这个方法有运气成分
class Solution {
public:int jump(vector<int>& nums) {return GetRes(nums,0,nums.size(),0);}
private:int GetRes(vector<int>&nums,int i,int size,int index){if(i>=size-1)return index;int dis=0;int op=0;for(int j=1;j<=nums[i];j++){if(i+j>=size-1)return index+1;if(nums[i+j]+j>dis){op=j;dis=nums[i+j]+j;}}return GetRes(nums,i+op,size,index+1);}
};
(3)贪心算法:
思路:提示信息表明,题目保证可以到达nums[ n-1 ],那么我们可以从结尾开始找开头,也就是逆向查找
我们知道,倒数第一步肯定是一步就到了nums[ n-1 ],我们就找出可以一步到达nums[ n-1 ]的位置,这个位置应该尽可能在左边,接近开头的位置
找到了这个位置,就依次类推,查找倒数第二步的位置
这个方法为什么可行呢?
正常的跳法是有规章的,不一定每一步都跳最长的距离,它需要计算到达nums[ n-1 ]的距离,我们这么贪心的查找,最后达到的位置应该是一般大于开头到末尾的距离的
这样的话,它跳跃的步数,就是一个简练的步数,因为每次都跳了最长的距离
不过,我觉得也有一部分原因是这道题并不严苛,主要是考察奇思妙想的
class Solution {
public:int jump(vector<int>& nums) {int web=nums.size()-1;int index=0;while(web>0){for(int i=0;i<web;i++){if(nums[i]+i>=web){web=i;index++;break;}}}return index;}
};
本次题解就到此为止了,你在碰到题目的时候,要想一下它在考察什么,不要小瞧了每一道题目,也不要高估了每一道难题,世界上没有完美的一道题目,有的只是想让你懂得什么的题目,所以不要盲目自大,看见这道题目出得不好,就贬低,甚至不屑于去看一眼,这样是错误的,也是最幼稚的一种态度,要常怀谦卑和包容,包容别人,也要包容自己
今天竟然在没到吃晚饭的时间就做好了,感觉自己的懒惰已经被消磨了,大大的进步,哈哈
在最后,纸上得来终觉浅,绝知此事要躬行