LeetCode跳跃游戏
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
思路:
这个题我们最容易想到的办法是模拟跳跃的行为,通过多次随机跳跃,假如我们可以遍历每一种跳跃路径的话,就可以知道最终能不能到达终点了。但问题是怎么模拟?我们会发现这是一个非常复杂的问题。比如对于nums = [2,3,1,1,4],从下标0可跳到下标1或下标2,假如在下标1,又可跳到下标2,下标3,下标4;假如在下标2,又可跳到下标3……可以发现这样的树-图将会非常复杂且不好操作。
所以我们要换个思路:我们的目标并不是求出每一种路径可以到达的最终结果,我们的目标只有一个:它能不能到达最后一个下标。我们把问题转化为:求出从起点可以跳跃到的最远距离,如果这个距离到达或超过了最后一个下标,则True,否则False。
那如何计算从起点开始可以跳跃到的最远距离呢?对于每一个位置,当前位置+它可以跳跃的距离,就是当前位置可以到达的最远距离,是吧?那我们只需要求出每一个位置的最远距离,取最大的那个即可。
但我们必须要采取顺序计算的方式,因为假如从位置1都到不了位置2,就算位置2的最大距离比位置1的最大距离大,我们也不能使用位置2的最大距离去代替结果。即要从前往后算,某个位置可以达到了,再计算某个位置的最远距离。
代码:
class Solution(object):
def canJump(self, nums):
max_dis = 0# 记录最远能跳到哪
for i,n in enumerate(nums[:-1]):#忽略最后一个位置
max_dis = max(max_dis,i+n) # 当前位置上,最远能跳到哪
if max_dis<=i: #如果当前的最大距离小于等于这个位置,说明没法往前走了
return False
return True
小结:
总体过程就是:一边向前走,一边试探能不能达到下一个下标位置,顺便慢慢更新我们的最大距离。
代码里我们忽略了最后一个位置的遍历,因为很显然当倒数第二个位置可以向前继续走(没有返回False)时,就必然可以到达最终下标了。相反,如果在此之前的任何一步返回False的话,证明它就停止在某处无法前进了,肯定是不能到达最终下标的。
可以发现,为了求解这个问题,我们并不需要绕一大圈子去遍历每一种跳跃路径和结果,稍微转变一下思路,就可以非常符合题意地得到结果。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 我与微信审核的“相爱相杀”看个人小程序副业
· DeepSeek “源神”启动!「GitHub 热点速览」
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库