# LeetCode045——跳跃游戏II

### 思路一：回溯法（在LeetCode中提交会超时）

JAVA代码：

//backtracking
public class Solution {

int steps;

public int jump(int[] nums) {
int n = nums.length;
steps = n - 1;

jump(nums, 0, 0);

return steps;
}

/*
* Now I'm in the indexth position of nums, I have take tempSteps steps
*/
private void jump(int[] nums, int index, int tempSteps) {
if(index >= nums.length - 1) {
if(index == nums.length - 1) {
steps = Math.min(steps, tempSteps);
}
return;
}
for (int i = 1; i <= nums[index]; i++) {
jump(nums, index + i, tempSteps + 1);
}
}
}

### 思路二：动态规划（在LeetCode中提交会超时）

（1）如果nums[x] + x >= y，说明一步就可以从索引x走到索引y，f(x, y) = 1。

（2）如果nums[x] + x < y，f(x, y) = 1 + min{f(x + 1,y), f(x + 2, y), ... , f(x + nums[x], y)}。

JAVA代码：

public class Solution {

//dynamic programming
public int jump(int[] nums) {
int n = nums.length;
if(n == 1) {
return 0;
}
int[][] steps = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
steps[i][j] = n - 1;
}
}
for (int i = 0; i < n; i++) {
steps[i][i] = 0;
}
for (int i = 0; i >= 1 - n; i--) {
for (int j = 0; j < n + i; j++) {
if(nums[j] + j >= j - i) {
steps[j][j - i] = 1;
}else {
for (int k = 1; k <= nums[j]; k++) {
steps[j][j - i] = Math.min(steps[j][j - i], 1 + steps[j + k][j - i]);
}
}
}
}
return steps[0][n - 1];
}
}

### 思路三：贪心算法

（1）如果此时i + k + p的最大值仍然小于数组的长度 - 1，说明经过此步还未能抵达数组中最后一个元素。

（2）如果此时i + k + p的最大值大于等于数组的长度 - 1，说明经过此步能抵达数组中最后一个元素，显然索引i + k是最优解。

JAVA代码：

public class Solution {

//greedy algorithm
public int jump(int[] nums) {
int n = nums.length;
int steps = 0;
int index = 0;
while(index < n - 1) {
steps++;
int[] lengths = new int[nums[index]];
if(index + nums[index] >= n - 1) {
break;
}
for (int i = index + 1; i <= index + nums[index]; i++) {
lengths[i - index - 1] = i + nums[i];
}
int max = 0;
for (int i = 0; i < lengths.length; i++) {
if(lengths[i] > lengths[max]) {
max = i;
}
}
index = max + index + 1;
}
return steps;
}
}

LeetCode解题报告：