当前位置: 首页 > 科技观察

跳跃游戏!你玩过吗?

时间:2023-03-21 23:03:10 科技观察

跳跃游戏链接:https://leetcode-cn.com/problems/jump-game给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表您可以在该位置跳跃的最大长度。确定您是否可以到达最后一个位置。示例1:输入:[2,3,1,1,4]输出:true解释:我们可以从位置0跳1步到位置1,然后从位置1跳3步到最后一个位置。示例2:输入:[3,2,1,0,4]输出:false解释:无论如何,你总是会在索引3处结束。但是那个位置的最大跳跃长度是0,所以你永远无法到达最后一个位置。刚看到这道题的时候,我可能会想:如果当前位置元素为3,是跳一步,跳两步,还是跳三步,多少步最好?实际上,跳多少步并不重要。关键在于跳跃的覆盖!不必指定一次跳多少步,每次取最大跳步数。这就是跳跃的覆盖。在这个范围内,不管你怎么跳,都绝对可以跳过去。那么这个问题就转化为跳跃覆盖能不能到达终点!为每次移动取最大跳跃步数(以获得最大覆盖范围),并在每次移动一个单元时更新最大覆盖范围。贪心算法的局部最优解:每次取最大跳数(取最大覆盖),整体最优解:最后得到整体最大覆盖,看能不能走到终点。局部最优导致全局最优,找不到反例,贪心试试!如图:跳跃游戏i每次只能在cover的范围内移动,每移动一个元素,cover获取元素的值(新的覆盖区域),让i继续移动。而cover每次只取max(元素值补完后的范围,cover本身的范围)。如果覆盖大于等于结束下标,直接返回true即可。C++代码如下:classSolution{public:boolcanJump(vector&nums){intcover=0;if(nums.size()==1)returntrue;//只有一个元素可以到达for(inti=0;i<=cover;i++){//注意这里是小于等于covercover=max(i+nums[i],cover);if(cover>=nums.size()-1)returntrue;//可以覆盖到最后了}returnfalse;}};总结这道题的重点就是:不要拘泥于每次跳多少步,要看覆盖面积。在覆盖范围内必须是可以跳过去的,不管是怎么跳的。可以看到思路已经想通了,代码还是很简单的。可能有的同学会觉得,我讲贪心系列的时候,好像和题目没有什么联系?**如果是真的,就没有任何联系,因为贪婪没有套路!**没有解决一系列问题的整体贪婪框架,只能接触各种类型的题目来锻炼你的贪婪思维!