116.Jump Game-跳跃游戏(中等题)

本文介绍了一种名为“跳跃游戏”的算法问题,探讨了如何判断能否从数组起始位置到达末尾。提供了三种解决方案:双指针法、动态规划法及贪心算法,并详细解释了每种方法的实现思路及代码。

跳跃游戏

  1. 题目

    给出一个非负整数数组,你最初定位在数组的第一个位置。   
    数组中的每个元素代表你在那个位置可以跳跃的最大长度。    
    判断你是否能到达数组的最后一个位置。

    注意事项
    这个问题有两个方法,一个是贪心和 动态规划。
    贪心方法时间复杂度为O(N)。
    动态规划方法的时间复杂度为为O(n^2)。
    我们手动设置小型数据集,使大家阔以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。

  2. 样例

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

  3. 题解

1.双指针O(n^2)
由于唯一会导致无法跳跃的情况就是数组中出现0,所以对数组进行遍历。如果找到A[i]=0,则对A[0..i-1]进行遍历,如果找不到一个数字可以使得可以跳过这个0(A[j] > i-j || (A[j] == i-j && i == A.length-1)),则返回false。

public class Solution {
 /**
 * @param A: A list of integers
 * @return: The boolean answer
 */
 public boolean canJump(int[] A) {
    if (A.length == 1)
    {
        return true;
    }
    for (int i=0;i<A.length;i++)
    {
        if (A[i] == 0)
        {
            boolean can = false;
            for (int j = i-1;j>=0;j--)
            {
                if (A[j] > i-j || (A[j] == i-j && i == A.length-1))
                {
                    can = true;
                    break;
                }
            }
            if (!can)
            {
                return false;
            }
        }
    }

    return true;
 }
}

2.动态规划O(n^2)
思路同解法1

public class Solution {
 /**
 * @param A: A list of integers
 * @return: The boolean answer
 */
 public boolean canJump(int[] A) {
    boolean[] can = new boolean[A.length];
    can[0] = true;
    for (int i=1;i<A.length;i++)
    {
        for (int j=0;j<i;j++)
        {
            if (can[j] && j + A[j] >= i)
            {
                can[i] = true;
                break;
            }
        }
    }

    return can[A.length-1];
 }
}

3.贪心法

尝试跳到最远,如果i在当前可以跳到的最远范围内,则查验从i可以跳到的最远处是否远于当前的farthest,如果是则将farthest替换成A[i] + i。遍历完成后,如果farthest可以达到数组长度则返回true。

public class Solution {
 /**
 * @param A: A list of integers
 * @return: The boolean answer
 */
 public boolean canJump(int[] A) {
    int farthest = A[0];
    for (int i = 1; i < A.length; i++) 
    {
        if (i <= farthest && A[i] + i >= farthest) 
        {
            farthest = A[i] + i;
        }
    }
    return farthest >= A.length - 1;
 }
}

Last Update 2016.10.13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值