leetcode45题:跳跃游戏II

1、题目描述

给出一个非负整数数组,你最初定位在数组的第一个位置。

数组中的每个元素代表你在那个位置可以跳跃的最大长度。   

你的目标是使用最少的跳跃次数到达数组的最后一个位置。

样例

给出数组A = [2,3,1,1,4],最少到达数组最后一个位置的跳跃次数是2(从数组下标0跳一步到数组下标1,然后跳3步到数组的最后一个位置,一共跳跃2次)

2、思想

利用贪心策略,用三个变量i,j和temp标识当前的位置,下一步要跳到的位置,和下一步能跳到的最远距离从而决定下一步跳到的位置(j)。

3、代码实现

class Solution {
    public int jump(int[] A) {
        if(A.length<=1){//判断数组是否符合要求
            return 0;
        }
        int i=0;//记录当前所在的位置
        int j=0;//表示下一步要跳到哪里
        int count = 0;//记录跳跃次数
        while(i<A.length){
            if(i+A[i]>=A.length-1){//i表示现在的位置,A[i]表示能够跳的最长位置
                count++;
                return count;
            }
            int temp = Integer.MIN_VALUE;////下一步所能跳到的最远距离
            for(int k=i+1;k<=i+A[i];k++){//最少前进一步,不能保持在原地不动,所以A[i]+i不参与比较
                if(temp<k+A[k]){
                    temp=k+A[k];
                    j=k;//记录能够跳的最远的位置,即从当前位置跳到这里
                }
            }
            i=j;//确定从当前位置要跳到哪里,使当前跳跃和下一次跳跃和的效果是最大的
            count++;
        }
        return 0;
        
    }
}

4、思想

利用动态规划,此题可以倒着想,

对于示例【2,3,1,1,4】

我们可以从后往前推,对于第4个数1,跳一次。

对于第3个数1,显然只能跳到第4个数上,那么从第3个数开始跳到最后需要两次。

对于第2个数3,显然一步到位,跳一次。

对于第1个数2,只能选择跳一次还是跳两次,显然选择跳一次的收益更大,最终只需跳两次。

倒着推时发现满足(1)最优子结构(2)重叠子问题。可以使用动态规划。

状态描述:f[i]表示在第i个位置最小需要几次可跳到最后一个位置。

状态转移方程:f[i] = min(f[i+1]~f[nums[i]])+1;

初始条件:f[nums.length()-1] = 0;//即最后一个数,跳0次即可到达最后。

5、代码实现

class Solution {
    public int jump(int[] nums) {
        int f[] = new int[nums.length];
        if (nums.length == 0) {
            return 0;
        }
        if (nums.length == 1) {
            return 0;
        }
        f[nums.length - 1] = 0;
        for (int i = nums.length - 2; i >= 0; i--) {
            f[i] = findMin(f, i, nums[i]) + 1;
            if (f[i] < 0) f[i] = Integer.MAX_VALUE;
        }

        return f[0];

    }

    private int findMin(int[] f, int i, int num) {
        int min = Integer.MAX_VALUE;
        for (int j = 1; j <= num && i + j < f.length; j++) {
            min = Math.min(min, f[i + j]);
        }
        return min;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值