116. 跳跃游戏
给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
判断你是否能到达数组的最后一个位置。
注意事项
这个问题有两个方法,一个是贪心
和 动态规划
。
贪心
方法时间复杂度为O(N)
。
动态规划
方法的时间复杂度为为O(n^2)
。
我们手动设置小型数据集,使大家可以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。
样例
A = [2,3,1,1,4],返回 true.
A = [3,2,1,0,4],返回 false.
一个很典型的动态规划问题
把这个数组看作一排点
如果能从X点跳到Y点,那么就连接这两个点
这样我们就构建了一个DAG
令F(n)表示为我们是否能到达n点
DAG(V, E)
init F(1..n)=false
for(1...n)
F(i)=true iff F(j)=true & (j,i) in E;
那么对于这个题来说,我们可以用一个和A大小一样的vector(bool)来记录我们是否能到达某个点。
1 bool canJump(vector<int> &A) { 2 // write your code here 3 vector<bool> canJump(A.size(), false); 4 int temp; 5 for(int i=0;i<A.size();i++){ 6 temp=i; 7 for(int j=0;j<A[i];j++){ 8 canJump[temp++]=true; 9 } 10 } 11 12 for(int i=0;i<canJump.size()-1;i++){ 13 if(!canJump[i]){ 14 return false; 15 } 16 } 17 18 return true; 19 }
同时,如果用贪心算法的话
遍历数组,对于每一个位置,计算出当前所能到的最远距离,并把当前距离与目前所能到的最远距离进行比较
1 bool canJump(vector<int> &A) { 2 // write your code here 3 int max_len = 0; 4 for (int i = 0; i < A.size(); ++i) { 5 if (i > max_len) 6 return false; 7 max_len = max(max_len, i + A[i]); 8 } 9 return true; 10 }