跳跃游戏
题目
给出一个非负整数数组,你最初定位在数组的第一个位置。
数组中的每个元素代表你在那个位置可以跳跃的最大长度。
判断你是否能到达数组的最后一个位置。注意事项
这个问题有两个方法,一个是贪心和 动态规划。
贪心方法时间复杂度为O(N)。
动态规划方法的时间复杂度为为O(n^2)。
我们手动设置小型数据集,使大家阔以通过测试的两种方式。这仅仅是为了让大家学会如何使用动态规划的方式解决此问题。如果您用动态规划的方式完成它,你可以尝试贪心法,以使其再次通过一次。样例
A = [2,3,1,1,4],返回 true.
A = [3,2,1,0,4],返回 false.题解
1.双指针O(n^2)
由于唯一会导致无法跳跃的情况就是数组中出现0,所以对数组进行遍历。如果找到A[i]=0,则对A[0..i-1]进行遍历,如果找不到一个数字可以使得可以跳过这个0(A[j] > i-j || (A[j] == i-j && i == A.length-1)),则返回false。
public class Solution {
/**
* @param A: A list of integers
* @return: The boolean answer
*/
public boolean canJump(int[] A) {
if (A.length == 1)
{
return true;
}
for (int i=0;i<A.length;i++)
{
if (A[i] == 0)
{
boolean can = false;
for (int j = i-1;j>=0;j--)
{
if (A[j] > i-j || (A[j] == i-j && i == A.length-1))
{
can = true;
break;
}
}
if (!can)
{
return false;
}
}
}
return true;
}
}
2.动态规划O(n^2)
思路同解法1
public class Solution {
/**
* @param A: A list of integers
* @return: The boolean answer
*/
public boolean canJump(int[] A) {
boolean[] can = new boolean[A.length];
can[0] = true;
for (int i=1;i<A.length;i++)
{
for (int j=0;j<i;j++)
{
if (can[j] && j + A[j] >= i)
{
can[i] = true;
break;
}
}
}
return can[A.length-1];
}
}
3.贪心法
尝试跳到最远,如果i在当前可以跳到的最远范围内,则查验从i可以跳到的最远处是否远于当前的farthest,如果是则将farthest替换成A[i] + i。遍历完成后,如果farthest可以达到数组长度则返回true。
public class Solution {
/**
* @param A: A list of integers
* @return: The boolean answer
*/
public boolean canJump(int[] A) {
int farthest = A[0];
for (int i = 1; i < A.length; i++)
{
if (i <= farthest && A[i] + i >= farthest)
{
farthest = A[i] + i;
}
}
return farthest >= A.length - 1;
}
}
Last Update 2016.10.13