代码改变世界

[LeetCode] 45. Jump Game II_ Hard tag: Dynamic Programming, Greedy

2019-04-24 10:41  Johnson_强生仔仔  阅读(255)  评论(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.

 

这个题目思路跟[LeetCode] 55. Jump Game_ Medium tag: Dynamic Programming思路很像,只不过用f(i) 来表示到目前的最少的步数。f(i) = f(j) + 1 if f(j) > - 1 and nums[j] >= i - j.

Note: 同样这个题目也是time limit exceed。

Update 06/21/2021 : Add Greedy solution. T: O(n), S: O(1)

Code:O(n * n)

class Solution:
    def jumpGame2(self, nums):
        n = len(nums)
        mem = [-1] * n
        mem[0] = 0
        for i in range(1, n):
            for j in range(0, i):
                if mem[j] > -1 and nums[j] >= i - j:
                    mem[i] = mem[j] + 1
                    break
        return mem[n - 1]

 

Greedy:   T: O(n), S: O(1)

Ideas:

     1. 利用greedy的做法,去看当前的index下一步应该跳到哪里?答案是跳到max(所有可以跳到的位置+跳到位置的jumps),比如下面我们跳到5,因为5 + jumps是最远的

 

 

     2. jumps来记录当前jump的次数;cur_end来记录当前我们能跳到的range的最后一位;fatest来记录当前我们能够到达的最远的位置

     3. 不用到n - 1, 因为考虑到n - 2时的jump就结束了,到n - 1不用再跳了

     4. for loop, 不停更新fatest

     5. 如果到了最远的range,那么jumps + =1, 然后更新fatest,再循环(注意题目条件有assume总是能够达到last index)

 

class Solution:
    def jump(self, nums: List[int]) -> int:
        fatest, jumps, cur_end, n = 0, 0, 0, len(nums)
        for i in range(n - 1):
            fatest = max(fatest, i + nums[i])
            if i == cur_end:
                jumps += 1
                cur_end = fatest
        return jumps