# 45. Jump Game II

**<font color=red>难度: Hard</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/jump-game-ii/

> 内容描述

```
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.

Your goal is to reach the last index in the minimum number of jumps.

Example:

Input: [2,3,1,1,4]
Output: 2
Explanation: The minimum number of jumps to reach the last index is 2.
    Jump 1 step from index 0 to 1, then 3 steps to the last index.
Note:

You can assume that you can always reach the last index.
```

## 解题方案

> 思路 1
******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******

我们可以用一个辅助函数helper(idx)，其返回值是我们到达index为idx的位置的最少步数

递归, 超时


```
class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        def helper(idx):
            if idx == 0:
                return [True, 0]
            res = sys.maxsize
            for i in range(idx):
                if nums[i] >= idx - i:
                    tmp = helper(i)
                    if tmp[0]:
                        res = min(res, 1 + tmp[1])
            return [False] if res == sys.maxsize else [True, res]
        return helper(len(nums)-1)[1]
```


> 思路 2
******- 时间复杂度: O(N^2)******- 空间复杂度: O(N)******


DP

dp[i]代表的是到达index为idx的位置的最少步数, 依然超时，最后2个case过不了

```
class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if not nums or len(nums) == 0:
            return 0
        dp = [sys.maxsize] * len(nums)
        dp[0] = 0
        for i in range(1, len(nums)):
            for j in range(i):
                if j + nums[j] >= i:
                    dp[i] = min(dp[i], dp[j]+1)
        return dp[-1]
```

> 思路 3
******- 时间复杂度: O(N)******- 空间复杂度: O(1)******


greedy solution, the current jump is ```[i, cur_end]```, and the ```cur_farthest``` is the farthest point 
that all of point in ```[i, cur_end]``` can reach, whenever ```cur_farthest``` is larger than the last point' index, 
return current ```jump+1```; whenever ```i``` reaches ```cur_end```, update ```cur_end``` to ```current cur_farthest```.


最好情况时间甚至可以到达lgN

最坏情况就是所有数字都是1，那么必须一步一步走到底，O(N)

beats 81.47%

```python
class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        cur_end, cur_farthest, step = 0, 0, 0
        for i in range(len(nums)-1):
            cur_farthest = max(cur_farthest, i+nums[i])
            if cur_farthest >= len(nums) - 1:
                step += 1
                return step
            if i == cur_end:
                cur_end = cur_farthest
                step += 1
        return step
```


