给定一个非负整数数组,你最初位于数组的第一个位置... --错误方法纠正

本文深入探讨力扣55题跳跃游戏的解决方案,从初始错误的思路出发,逐步修正并优化算法,最终提出一种高效简洁的方法。通过详细分析不同场景下0元素的影响,以及如何正确处理这些特殊情况,文章提供了宝贵的编程经验和技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

力扣55题在这里插入图片描述

闹心,太闹心了,上周空闲时间写了一个自动钻取的,结果发现把0搞进去之后各种问题,房子越补漏雨越大,刚才琢磨了一下,真的是方向错了。
先来聊聊之前的方案,以此数组为例:

int[] nums = {2, 1, 1, 1, 3};
lastIndex = nums.length - 1;
startIndex = lastIndex - lastIndexVal;  //第一个下标

1、从后往前遍历,根据当前数组值判断可以跳到当前位置的下标,
2、第一个遍历值是3(lastIndex 是4),所以可以获取到startIndex 为1(4 - 1 = 3),然后判断startIndex的数组值是否大于等于3,
<1、不等于:给3减1,然后获取到startIndex = 3 - 1 ,再重复2步骤
<2、等于:lastIndex = startIndex

大体就是这样,但是把0加进来后,一切都变了,
出现 0 的总共有好几种情况

  1、第一个下标值是 0    {0, 1, 1, 1, 3}   //好办,第一个是 0 直接就可以停了
  2、最后一个是 0   {1, 1, 1, 1, 0}   //开始需要加判断了
  3、中间好多0   {1, 1, 0, 0, 1}    //缝缝补补又是一套
  ...

最后就是写了70多行,声明了7个公共变量还是一坨shi。
不多说了,直接看新代码,10行搞定

int[] nums = {3, 1, 2, 0, 0};
int countO = 0;

for (int i = nums.length - 1; i >= 0; i--) {
    if (nums[i] == 0) {
        ++countO;
    } else {
        if (nums[i] >= countO) {
            countO = 0;
        } else {
            countO++;
        }
    }
}

if (countO == 0) {
    System.out.println("成功");
} else {
    System.out.println("失败");
}

就这样,遇到 0就递增,不是0的判断是否可以达到积攒0的最大值,达不到就继续递增,达到了就清0
完了!

2021-4-22更新

if (nums[i] >= countO) {

上面第8行判断有问题,先补充一下实现逻辑。
从后往前遍历,遇见非0的数不用处理,因为非0的都可以正常跳过去;
遇见0就计数,以 {3, 1, 2, 0, 0,1}为例,遍历到倒数第1个0时,计数器加1,再遍历到倒数第2个0计数器加到2,然后呢,遍历到2的时候,需要判断2是不是大于2(计数器值)。就这块,之前判断的是大于等于,但是不应该加上等于,等于的话就跳到倒数第一个0上面了,而正确的应该是把两个0都跳过去,示意图如下

在这里插入图片描述




抱歉抱歉诸位,上面那方法是错的。把数组第一位改成0它也会成功的(太尴尬了)。
刚才重新写了下,刚开始本来打算用无限嵌套循环的,从第1位开始,跳到能到达的最大步数,然后再跳能到达的最大步数,跳不到就给上一步的最大步数 -1 再往后跳,如果往复,简直太麻烦了,最后写了3个数组,仔细看了下研究出规律来了然后有了下面的进化版:

        // 1、遇到0就停,逐个判断前面的能不能从当前0跳过去
        // 2、能跳过去就继续判断0后面的数
        // 3、不能跳过去就失败终止
        int[] nums = {0, 1, 0, 1, 0, 2, 3};
        boolean isFail = false;
        for (int i = 0; i < nums.length; i++) {
            int step = nums[i];
            if (0 == step) { // 遇到0就停下判断
                for (int j = i - 1; j >= 0; j--) {
                    int lastNum = i - j + 1;
                    if (nums[j] >= lastNum) { // 能跳过去就继续遍历
                        break;
                    } else {
                        if (j == 0) { // 到第一位就证明失败了
                            isFail = true;
                        }
                    }
                }
            }
            if (isFail) {
                break;
            }
        }
        if (!isFail) {
            System.out.println("成功");
        } else {
            System.out.println("失败");
        }

欢迎测试指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值