力扣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("失败");
}
欢迎测试指正