public boolean canJump(int[] A){
  if (A == null || A.length == 0)   return false;
  if (A.length == 1)   return true;
  if (A[0] == 0)   return false;
  int maxJump=A[0];
  for (int i=1; i < A.length - 1; i++) {
    maxJump=Math.max(maxJump - 1,A[i]);
    if (maxJump == 0)     return false;
  }
  return true;
}

public boolean canJump ( int [ ] A ) { if ( A == null || A . length == 0 ) return false ; if ( A . length == 1 ) return true ; if ( A [ 0 ] == 0 ) return false ; int maxJump = A [ 0 ] ; for ( int i = 1 ; i < A . length - 1 ; i ++ ) { maxJump = Math . max ( maxJump - 1 , A [ i ] ) ; if ( maxJump == 0 ) return false ; } return true ; }
dynamic programming keep track of the maximum of jumps we left initialized as a [ 0 ] traverse from second to second last reduce 1 every time we jump maxjump should be max of maxjump - 1 and a [ i ] if maxjump reduces to zero , we are not able to reach anymore
