LeetCode-45. Jump Game II

0.原题

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.代码

class Solution:
    def jump(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        if length <= 1:
            return 0
        self.nums = nums
        self.length = length
        self.step = 1
        self.fun(0,nums[0])
        return self.step

    def fun(self,start,end):
        if end >= self.length-1:
            return 0
        self.step += 1
        farthest = start + self.nums[start]
        for index in range(start+1,end+1):
            if farthest < index + self.nums[index]:
                farthest = index + self.nums[index]
                new_start = index
                new_end = index + self.nums[index]
        self.fun(new_start,new_end)

2.思路

首先,解决第一步怎么跳

假设nums[0] = x,那么从0出发,最远可以走到x位置。那么我们第一步就有x种选择,可以选择走到1,2,3,……,x-1,x;

究竟跳到哪一格才是最优的呢?本文先给出结论,再做说明:

结论:

如果,nums[i] +i= max(nums[1]+1,nums[2]+1,nums[3],……,nums[x-1],nums[x]),第一步应该走到i位置。

即:在[1:x]区间中,依次计算(nums[i]+i),值最大的位置就是最佳落点

为什么:

先看4点事实:

  1. nums[0] = x,那么从0出发,只能跳到[1:x]中的一个点,所以这是一个x种方案的寻优问题;
  2. 这一次jump的落点一定<=x,下一次jump的落点一定>=x+1。否则,两次jump操作可以合并为一次;
  3. nums[i] +i:表示从位置i出发,所能够到达的最远距离。那么,下一次的jump的落点选择区间为[i+1:nums[i]+i];
  4. 如果nums[i]+i > nums[j]+j,那么区间[x+1 : nums[i]+i]属于区间[x+1: nums[i]+i] 。这说明,jump到能够使得(nums[i]+i)更大点,将会是更优的方案。

因此,第一步jump的最优方案是:jump到(nums[i] +i)最大的点。

可见,我们已经找到了从起点出发,jump到最优点的方法。

然而,每一次jump之后,上一次的落点,就变成了新的起跳点!

所以,我们只要重复上述步骤,直至终点即可。

猜你喜欢

转载自blog.csdn.net/qq_17753903/article/details/83239872