跳跃游戏Jump Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

Example 1:

Input: [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

Example 2:

Input: [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum
jump length is 0, which makes it impossible to reach the last index.

这道题说的是有一个非负整数的数组,每个数字表示在当前位置的基础上最多可以走的步数,求判断能不能到达最后一个位置(可以超过最后一个位置)。

方法一:

用贪婪算法Greedy Algorithm,因为我们并不是很关心每一个位置上的剩余步数,我们只希望知道能否到达末尾,也就是说我们只对最远能到达的位置感兴趣,所以我们维护一个变量location,表示最远能到达的位置,初始化为0。遍历数组中每一个数字,如果当前坐标大于location或者location已经抵达最后一个位置则跳出循环,否则就更新location的值为其和i + nums[i]中的较大值,其中i + nums[i]表示当前位置i能到达的最大位置。

#include<iostream>
using namespace std;
#include<vector>

class Solution{
public:
	bool canJump(vector<int>& nums) {
        int location = 0;
        for(int i=0; i<nums.size(); i++){
        	if(i>location || location>=(nums.size()-1)) break;  //i>location说明永远也不可能跳到终点了,location>=(nums.size()-1说明已经能跳到终点了
        	location = max(location,i+nums[i]);  
       		//好好理解上面这句话,意思就是把location之前的数值都可以加起来看看,如果大于location,那就更新location。
        }
        return location>=(nums.size()-1);
    }
};

int main(){
	Solution S;
	vector<int> nums = {2,3,1,1,4};
	cout<<S.canJump(nums);
	return 0;
}
方法二:

用动态规划Dynamic Programming来解,我们维护一个一位数组dp,其中dp[i]表示达到i位置时剩余的步数,那么难点就是推导状态转移方程啦。我们想啊,到达当前位置的剩余步数跟什么有关呢,其实是跟上一个位置的剩余步数和上一个位置的跳力有关,这里的跳力就是原数组中每个位置的数字,因为其代表了以当前位置为起点能到达的最远位置。所以当前位置的剩余步数(dp值)和当前位置的跳力中的较大那个数决定了当前能到的最远距离,而下一个位置的剩余步数(dp值)就等于当前的这个较大值减去1,因为需要花一个跳力到达下一个位置,所以我们就有状态转移方程了:dp[i] = max(dp[i - 1], nums[i - 1]) - 1,如果当某一个时刻dp数组的值为负了,说明无法抵达当前位置,则直接返回false,最后循环结束后直接返回true即可

#include<iostream>
using namespace std;
#include<vector>

class Solution{
public:
	bool canJump(vector<int>& nums) {
		vector<int> bp(nums.size(),0); //初始化bp数组,全零,长度为nums的长度,bp表示根据当前跳力还能跳几步
		for(int j=1; j<nums.size(); j++){
			bp[j] = max(bp[j-1],nums[j-1])-1;  
			//好好理解这句话,可以手写看看。bp[j]和bp[j-1]本身就相差一步,所以要减一(从j-1位置到j位置,要耗费一步)
			//站在j位置上,还能用跳力跳几步?要看前面的剩余跳力和当前的跳力哪个大,哪个跳力大我们就选哪个,这样才跳得远
			if(bp[j]<0) return false;   //bp[j]==0说明不能再跳了,停在此步,bp[j]小于0说明上一步往前跳是错误的。
		}
		return true;
	}
};

int main(){
	Solution S;
	vector<int> nums = {2,3,1,1,4};
	cout<<S.canJump(nums);
	return 0;
}

参考网址:http://www.cnblogs.com/grandyang/p/4371526.html
https://leetcode.com/problems/jump-game/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值