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
梦想还是要有的,万一实现了呢~~~~ ヾ(◍°∇°◍)ノ゙~~~~