1. 程式人生 > >LeetCode-45. Jump Game II

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之後,上一次的落點,就變成了新的起跳點!

所以,我們只要重複上述步驟,直至終點即可。