[ LeetCode ] #45. Jump Game II( 跳跃比赛II ) C++ & Python

该博客讨论了LeetCode中的45号问题‘跳跃游戏II’,并提供了使用C++和Python解决此问题的算法。博主分析了问题的题意,指出可以使用动态规划(DP)方法来求解,通过遍历数组并更新每个位置的最小跳跃次数来达到目标。博客还提到了如何优化算法,避免不必要的计算,以提高运行效率。最后,列出了代码实现及运行时间与内存使用情况。
摘要由CSDN通过智能技术生成

题目:45. 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--- nums[i]种跳法,并且到达每一位置的最少跳跃次数受前一次结果的影响,因此可以使用DP,主要思路如下:

  1. 构建与所给数列同等大小的dp,并用INT_MAX初始化dp,表示初始到达所有位置的跳跃次数;
  2. 将dp[0] 置为 0 ,因为从0处出发。
  3. 遍历数列,并且以当前位置为跳跃点,更新所能到达的所有位置,更新到达后面每一位置的最小跳跃数。
  4. 过滤掉当前位置后面连续的若干 个跳跃范围被当前位置所覆盖的点(节省不必要的计算,负责边界值会超时)即2,3,1,1,4,5 这种情况 当遍历到3的时候,后面的两个1的位置其实是没有意义的,因为它们的可跳跃范围已经被3所包含在内。

Code & C++

class Solution {
public:
    int jump(vector<int>& nums) {
        std::ios::sync_with_stdio(0);
        cin.tie(0);
        int len = nums.size();
        if(len<=1)return 0;
        vector<int> dp(len, INT_MAX);
        int j,idx;
        dp[0]=0; 
        for(int i=0;i<len;++i){
            j=1;
            // 更新当前位置可以到达的位置的跳跃需求次数
            while(j<=nums[i] && i+j<len){
                dp[i+j]=min(dp[i]+1, dp[i+j]);
                ++j;
            }
            idx=1;
            // 过滤当前位置所覆盖了的起跳位置
            while(i+idx<len && nums[i+idx]+idx<=nums[i])++idx;
            i+=idx-1;
        }
        return dp[len-1];
    }
};

 

Code & Python

class Solution:
    def jump(self, nums: List[int]) -> int:
        nlen = len(nums)
        dp = [1<<31]*nlen
        dp[0], i = 0, 0
        while i < nlen:
            j, idx = 1, 1
            flag = True
            while i+j < nlen and j <= nums[i]:
                dp[i+j] = min(dp[i+j], dp[i]+1)
                if flag and nums[i+j]+j <= nums[i]:
                    idx = j
                else:
                    flag = False
                j += 1
            if idx>1:
                i += idx-1
            else:
                i += 1
        return dp[nlen-1]

Runtime: 68 ms, faster than 37.84% of Python3 online submissions for Jump Game II.

Memory Usage: 14.5 MB, less than 7.50% of Python3 online submissions for Jump Game II.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值