一.跳跃游戏1
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
两种方法贪心算法和动态规划
1.贪心算法代码如下:(我也不太理解,希望谁可以补充的更仔细)
public canJump(int[] A){
int end=0;
for(int i=0;i<A.length-1;i++){
if(i<end&&i+A[i]>end)
end=i+A[i];
}
return end>=A.lemgth-1;
}
2.动态规划代码如下:
说实话,自己的动态规划还是很弱,有待加强!
动态规划的思路相对来说要复杂一下,我们这里分两种情况来讨论
第一步,定义一个dp一维数组,用来记录每个位置是否能够达到终点。比如,dp[i],表示在i位置,是否能够跳到终点,如果能,为true;反之为false。
第二步,dp[i]是否能够跳到终点,这里主要分为两种情况:
1.如果当前位置可以直接跳到终点,也就是说i + A[i] >= A.length() - 1,那么直接让dp[i] 为true就行了。
2.如果当前位置不能直接跳到终点,但是可以借助其他位置跳到终点,那么dp[i]也为true。这里设置为true有两个条件,假设它借助j位置,首先dp[j]必须true,其次它必须能够跳到j位置,也就是说i + dp[i] >= j。
经过简单的分析,应该能够理解到这个解法的思路吧!!!
class Solution {
//动态规划
public boolean canJump(int[] A) {
boolean dp[] = new boolean[A.length];
//默认最后一个为true
dp[A.length - 1] = true;
for (int i = A.length - 2; i >= 0; i--) {
//如果当前位置能够直接跳到终点,直接设置为true
if (i + A[i] >= A.length - 1) {
dp[i] = true;
}
else
for (int j = i; j < A.length - 1; j++) {
//设置为true的条件是:
//1.借助的j点必须为true
//2.必须能够跳到j点来(i + A[i] >= j)
if (dp[j] && i + A[i] >= j) {
dp[i] = true;
}
}
}
return dp[0];
}
}
二.跳跃游戏2!!!!!
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
你的目标是使用最少的跳跃次数到达数组的最后一个位置。
输入: [2,3,1,1,4]
输出: 2
解释: 跳到最后一个位置的最小跳跃数是 2。
从下标为 0 跳到下标为 1 的位置,跳 1 步,然后跳 3 步到达数组的最后一个位置。