您的位置:首页 > 其它

lintcode 跳跃游戏(116)

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


 注意事项


这个问题有两个方法,一个是
贪心
和 
动态规划

贪心
方法时间复杂度为
O(N)

动态规划
方法的时间复杂度为
为O(n^2)

我们手动设置小型数据集,使大家可以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。

您在真实的面试中是否遇到过这个题? 

Yes

样例

A = [2,3,1,1,4],返回 true.
A = [3,2,1,0,4],返回 false.
***********************************************************************************
法一:
常规思路,考虑,因为存在0的情况,才导致不可达最后一个位置。都是整数,则一定可达。
考虑出现0的处理办法,只要出现0之前某数可以越过0所对应的位置即可。
例如A = [3,3,1,0,4],i=3时A[i]=0,而A[1]>(3-1)即可越过该0。

class Solution {
public:
/**
* @param A: A list of integers
* @return: The boolean answer
*/
bool canJump(vector<int> A) {
// write you code here
if(A.size()==1) return true;
if(A[0]==0) return false;
for(int i=1;i<A.size()-1;i++){
if(A[i]==0){
for(int j=i-1;A[j]<=(i-j);j--){
if(j==0)
return false;
}
}
}
return true;
}
};


法二:
动态规划,找状态转移方程。
令d[i]表示当前i下可达最远距离。只要d[i]>=A.size()-1即可。
d[i] = max{A[i]+i, d[i-1]}

bool canJump(vector<int> A) {
// write you code here
if(A.size()==1) return true;
if(A[0]==0) return false;
vector<int> d(A.size());
d[0]=A[0];
for(int i=1;i<A.size();i++){
if(d[i-1]>=i)
d[i]=max(A[i]+i,d[i-1]);
else
d[i]=0;
}
return (d[d.size()-1] >= d.size()-1);
}


法三:
贪心思想,本来想通过m=m+A[m]来加快遍历的,后面发现会陷入死循环中,需要讨论的情况比较多,后面还是用直接遍历得了。
其实在法二中,d数组只用到了最远距离,现在用一个m记录可以达到的最远距离。
用i遍历数组,当i>m,则代表,i点不可达,返回false;
当i>=A.size()-1,则说明可以到达最后。
bool canJump(vector<int> A) {
// write you code here
if(A.size()==1) return true;
if(A[0]==0) return false;
int m=A[0];
for(int i=0;i<A.size();i++){
if(i>m) return false;
if(i+A[i]>m)
m=i+A[i];
if(m>=A.size()-1)
return true;
}
}

a215
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: