Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.

 

原题链接: http://oj.leetcode.com/problems/jump-game/ 
这道题是动态规划的题目,所用到的方法跟是在Maximum Subarray中介绍的套路,用“局部最优和全局最优解法”。我们维护一个到目前为止能跳到的最远距离,以及从当前一步出发能跳到的最远距离。局部最优local=A[i]+i,而全局最优则是global=Math.max(global, local)。递推式出来了,代码就比较容易实现了。因为只需要一次遍历时间复杂度是O(n),而空间上是O(1)。代码如下: 

  1. public boolean canJump(int[] A) {  
  2.     if(A==null || A.length==0)  
  3.         return false;  
  4.     int reach = 0;  
  5.     for(int i=0;i<=reach&&i<A.length;i++)  
  6.     {  
  7.         reach = Math.max(A[i]+i,reach);  
  8.     }  
  9.     if(reach<A.length-1)  
  10.         return false;  
  11.     return true;  
  12. }  

这 也是一道比较经典的动态规划的题目,不过不同的切入点可能会得到不同复杂度的算法,比如如果维护的历史信息是某一步是否能够到达,那么每一次需要维护当前 变量的时候就需要遍历前面的所有元素,那么总的时间复杂度就会是O(n^2)。所以同样是动态规划,有时候也会有不同的角度,不同效率的解法。这道题目还 有一个扩展Jump Game II,有兴趣的朋友可以看看。

 

 

class Solution {
public:
    bool canJump(int A[], int n) {
        if (n <= 1) return true;
        
        int start = n - 1;
        for (int i = n - 2; i >= 0; i--) {
            if (i + A[i] >= start) start = i;
        }
        
        return start == 0;
    }
};

 

class Solution {
public:
    bool canJump(int A[], int n) {
        if(NULL == A || n < 1) return false;
        
        int reach = 0;
        for(int i = 0;i < n;++i)
        {
            reach = max(A[i] + i,reach);
            if(A[i] == 0 && reach <= A[i] + i && reach < n - 1) return false;
        }
        if(reach < n - 1) 
            return false;
            
        return true;
    }
};

 

posted on 2015-01-06 10:43  风云逸  阅读(89)  评论(0)    收藏  举报