LeetCode 热题 HOT 100 第25天:“跳跃游戏”

继续刷LeetCode 热题 HOT 100 的题目,并且在博客更新我的solutions。在csdn博客中我会尽量用文字解释清楚,相关Java代码大家可以前往我的个人博客jinhuaiyu.com中查看。
题目:跳跃游戏
给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例 1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例 2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 , 所以永远不可能到达最后一个下标。
提示:
1 <= nums.length <= 3 * 104
0 <= nums[i] <= 105

solution:贪心算法
在讲具体步骤之前,我们先分析一下题目。如果只是简单地看,只会有三种情况:1、该数组中没有0,则一定能到达尾部;2、该数组中有若干个0,但每个0都能被跨过,比如i位置是第一个0,那么0到i-1位置中一定至少有一个数比这个位置到第一个0的距离大(跨过);3、该数组中有若干个0,但其中至少有一个0不能被跨过,比如4321012这组数字,0就无法被跨过。
这样看来,我们要分析每一个0能不能被跨过(即每一个0之前的数有没有大于两者距离的)。但是我们做题不是为了做一道题,而是为了做一类题,通过看评论区,我发现大家也有这种看法,就是这道题不是为了让大家去针对0进行分析,而是为了得出一种思想,对于这道题来说就是对每个数都要进行分析(但显然,这道题里如果没有0那肯定能到达尾部)。
如果用动态规划分析每个位置能不能被跨过,那时间复杂度至少是O(n²),我们需要思考的是怎么通过一轮遍历来分析。
我们也不需要维护每一个位置能跳到最远的距离,假设目前已经能到位置i,我们只需要维护前面所有位置能跳到最远处中最远的位置,farthest变量记录它,初始化为0。此时我们的移动并不是通过考虑能跳到什么位置,而是直接遍历每一个位置。从左往右遍历,如果当前位置在farthest内(说明当前位置是能跳到的),就可以继续遍历(位置+1),当然,需要通过对比原farthest和当前位置能跳到最远的位置来更新farthest。这种更新farthest可以看作是动态规划的一种变形,因为每次移动,都要看这个位置是否能从以前的位置跳过来(不超过farthest)。如果某次更新的farthest已经超过数组最后位置,说明能到达尾部,不用再往前移动一位来分析了。如果当前遍历位置超过了之前所有位置能达到的最远位置(不在farthest内了),说明这一步位置都根本到不了,更别说后面的位置了,此时跳出循环返回false。
其实这个循环遍历就是探讨当前位置能否达到,并更新前面(包括这个位置)所有能达到的位置中能跳到的最远处位置,不论你是跳几步,最远都只能到那,如果超过数组长度,说明能到尾部;如果中间某一个位置无法达到,说明到不了尾部。
这是一种从前往后遍历分析的方法,我们也可以从后往前分析,甚至还有其他的变形,但是理论都是这一套,去分析当前位置能否达到。

Finally,带有详细注释的代码放在我的个人博客http://jinhuaiyu.com/leetcode-jump-game/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值