leetcode45.跳跃游戏II——学习笔记

题目:力扣https://leetcode-cn.com/problems/jump-game-ii/

class Solution {
    public int jump(int[] nums) {
        if(nums.length==1){
            return 0;
        }
        return greedAlgorithm(nums);
    }

    private int greedAlgorithm(int[] nums){
        int len = nums.length;
        int distance = len-1;
        int pedometer = 0;
        int i = 0;
        int max = 0;
        boolean flag = false;
        while(true){
            max = 0;
            int maxValue = -1;
            for(int j=0;j<=nums[i];j++){//遍历可以选择的元素
                if(nums[i+j]>=distance){//查看是否可能直达目标
                    flag = true;
                    if(j!=0 && distance>1){
                        pedometer++;
                    }
                    break;
                }
                if(nums[i+j]+i+j>=maxValue){//找到最大值的下标(除了自己以外最大的值)
                    max = i+j;
                    maxValue = nums[max]+i+j;
                }
            }
            if(flag==false){//暂且不能一步到,选最大值
                i = max;
                pedometer++;
                distance = (len-1)-i;
            }else{//一步到达
                pedometer++;
                break;
            }
        }
        return pedometer;
    }
}

思路:这题叫“跳跃游戏II”,按道理应该还有一题叫“leetcode55.跳跃游戏”,可我尚未遇到,等我遇到那题我再补充把。我是使用贪心算法解题,还没看题解,所以代码啰啰嗦嗦一大堆,回头再看看大佬的题解。贪心,顾名思义就是每一次取值都取“收益”最大的元素,这题中的收益就是“跳跃距离”。这题中的收益不仅仅跟每个位置可跳跃距离有关,跟每个位置的下标也有关系。它们二者需要结合起来当作一个指标来考虑。每一次跳远,判断是否能够“一步登天”,若能则按照既定路线一步登天;若不能,则每次都选择收益最大的一步来跳跃。

1.写一个贪心算法的方法,传入题目给定的数组,传出最少的跳跃步数。

private int greedAlgorithm(int[] nums){
    //......
}

2.声明一堆变量。len是给定数组长度;distance是实际距离终点的距离;pedometer是计步器,记录跳了多少步;i表示当前位置的下标,默认值为0;max表示收益最大位置的下标,默认值为0;flag表示是否可以“一步登天”的状态,默认值为false;

int len = nums.length;
int distance = len-1;
int pedometer = 0;
int i = 0;
int max = 0;
boolean flag = false;

3.while每循环一次,就是跳了一步,每跳一步都需要重置max(收益最大一步的下标)和maxValue(收益最大时可跳跃的长度),以便后续判断。通过for循环遍历当前可选择的元素,判断当前一步是否有可能“一步登天”。若“脚下”所站的元素的值大于distan或遍历到可选的值大于distance即表示可以一步上岸,则改变信号旗flag的值,则跳出for循环不需要再遍历后面的元素了。若“脚下”所站的元素的值就大于distance,则只需1步;若只是遍历可选元素的值大于distance则需要先跳到该可选元素上再跳到重点,则需要2步,此处应作判断进行分类讨论。

若不能“一步登天”,则判断那一步“收益最大”。收益的计算公式:收益=该位置的值+该位置的下标。遍历完每一个可选择的位置后,得出当前“收益最大”的一步并记录这一步的下标和“收益”,将这个位置作为下一步的起跳位置。

while(true){
    max = 0;
    int maxValue = -1;
    for(int j=0;j<=nums[i];j++){//遍历可以选择的元素
        if(nums[i+j]>=distance){//查看是否可能直达目标
            flag = true;
            if(j!=0 && distance>1){
                pedometer++;
            }
            break;
        }
        if(nums[i+j]+i+j>=maxValue){//找到最大值的下标(除了自己以外最大的值)
            max = i+j;
            maxValue = nums[max]+i+j;
        }
    }

    //......
}

4.根据flag的信号,判断是否能够“一步登天”。若flag的值为false,则表示“革命尚未成功,同志仍需努力!”就老老实实更新i的位置,记录好步数pedometer,更新新的离终点距离distance,准备开始下一轮的while循环。若flag的值是true,则表示已经看到“胜利”的曙光了,按部就班的步数加1次,然后直接break跳出while循环。

if(flag==false){//暂且不能一步到,选最大值
    i = max;
    pedometer++;
    distance = (len-1)-i;
}else{//一步到达
    pedometer++;
    break;
}

5.跳出while循环后,将计步器pedometer作为出参返回。

return pedometer;

6.在主方法中先排除一些“搞事情”的例子(那些只有一个元素的,您就别搁着蹦了,直接返回0。)

if(nums.length==1){
    return 0;
}

7.调用greedAlgorithm(),返回该方法传出来的计步器上的值即可。

return greedAlgorithm(nums);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hokachi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值