数组跳跃游戏 Jump Game

142 篇文章 20 订阅
21 篇文章 0 订阅

题目源自于leetcode。

题目: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.
For example:

A = [2,3,1,1,4], return true.
A = [3,2,1,0,4], return false.

思路一:依靠题目的规则循规蹈矩。

    解题的一个重要思想是想到各种极端情况,考虑周全。

    数组中的数都是非负整数,所以如果数组内没有0的话,一定是从开始能跳到最后的。如果有0的话,必须有办法跳到0的右边去。

极端的一个情况是这样的,543210...那么怎么也跳不到0右面。所以至少需要0的左边有个数的大于它到0的距离。

刚才只考虑了单独1个0,对于连续的多个0,就需要其左边的某个数大于到最右的0的距离。

另外,不管最后一个数是什么,只要到达它即可,所以我的首个研究对象应该是倒数第二个数。

    

解决步骤:根据这个思路,我对数组从右向左遍历。当遇到0或0s时,就开始判断其左边是否存在值大于到最右0的距离的数。当再次遇到0或0s时,若没有找到这样的数,则宣布失败(无法完成跳跃);若有这样的数,重新开始下一轮判断。该方法时间复杂度为O(N)。

注意每个while遍历的都应该做超出边界值的检查。

class Solution {
public:
    bool canJump(int A[], int n) {
	if(A == NULL || n <= 0)
		return false;
  	int i = n-2;
	int idx_0;
	int flag;

  	while(i >= 0)
	{
		if(A[i] == 0)
		{
			flag = 0;
			idx_0 = i;
			i--;
			while(i >=0 && A[i] == 0)
				i--;
			while(i >=0 && A[i] != 0)
			{
				if(A[i] > idx_0 - i)
					flag = 1;
				i--;
			}
			if(flag == 0)
				return false;
			else
				continue;
		}
		i--;
	}
	return true;
    }
};

思路二:贪心法。记录一个变量保持最远可达的位置。从左到右遍历时,不断刷新这个最远距离。

class Solution {
public:
    bool canJump(int A[], int n) {
        int reach = 1;
        for(int i=0;i<reach && reach < n;i++)
            reach = max(reach, i + 1 + A[i]);
        return reach >= n;
    }
};
思路三:动态规划法。不过在此就没必要了,空间复杂度太高。
class Solution {
public:
    bool canJump(int A[], int n) {
        vector<int> v(n, 0);
        for(int i=1;i<n;i++)
        {
            v[i] = max(v[i-1], A[i-1]) - 1; //状态递推
            if(v[i] < 0) 
                return false;
        }
        return v[n-1] >= 0;
    }
};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值