跳步游戏

leetcode 55. Jump Game

一、问题描述

    给定一个非负整数数组,定义初始位置在数组的首位,数组内的每一个元素表示该位置的最大跳跃长度。判断是否能够到达数组最后的位置。
【举例】
<例 1>
输入: [2,3,1,1,4]
输出: true

解释: 从索引0到索引1跳一步, 从索引1跳三步到达最后的位置。

<例 2>
输入: [3,2,1,0,4]
输出: false
解释: 无论如何,总会到达索引3。 它的最大跳转长度为0,所以不可能达到最后的索引。

二、解题思路

思路一:动态规划

思路二:贪心 -- 正向

思路三:贪心 -- 逆向

三、思路一 -- 动态规划

设f(i)表示 能否从前面的j位置元素跳到当前的i位置,则状态转移方程为:

  • f(i) = f(j) && (i-j)∈nums[j]   0 <= j < i < numsSize
  • 边界条件为:f(0) = true

这里一但发现f[numsSize-1]位置的值为true,则可以马上返回true,因为题意只是确定能否到达,有一种情况到达即可立即返回

/************************************************************
author:tmw
date:2018-6-1
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool canJump(int* nums, int numsSize)
{
    bool* f=(bool*)malloc(numsSize*sizeof(bool));
    f[0] = true;
    int i,j;
    for(i=1;i<numsSize;i++)
    {
        for(j=0;j<i;j++)
        {
            f[i] = f[j] && ( (i-j)<=nums[j] );
            if(f[i]==true) //一旦发现该位置为可跳转位置(true),立即设true,找下一个位置是否可跳转
                break;
        }
    }
    return f[numsSize-1];
}

四、思路二 -- 贪心(正向)

从0 出发,一层一层往上跳,看最后能不能超过最高层,能超过,说明能到达,否则不能到达。

#define max(a,b) (a>b?a:b)
bool canJump(int* nums, int numsSize)
{
    int reach=1; //reach表示当前位置下的长度
    int i;

    //i<reach这个条件是为了看当前点跳了最右跳步数后能不能到达后面的点,不能到达就结束for循环---只有当前结点能往右跳,才能继续找max_reach
    //reach<numsSize这个条件是将numsSize长度设为终点,终点不参与跳步
    for( i=0; i<reach&&i<numsSize; i++ )
        reach = max(reach,i+1+nums[i]);

    return reach>=numsSize;
}

五、思路三 -- 贪心(逆向)

从最高层下楼梯,一层一层下降,看最后能不能下降到第0层。

bool canJump(int* nums, int numsSize)
{
    int target_index = numsSize-1;
    int i;
    for(i=numsSize-2; i>=0; i--)
    {
        //判定从当前位置能不能跳到目标位置
        if( nums[i]+i >= target_index )
            target_index = i;
    }
    return target_index == 0;
}

六、执行结果

accept


梦想还是要有的,万一实现了呢~~~~ ヾ(◍°∇°◍)ノ゙~~~~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值