2765. 最长交替子数组
1.题目介绍
2.题解
2.1 双层循环
思路
注意到这里:s1 = s0 + 1 。所以是以较小数开始的,极大简化了题目难度
接下来我们便可以通过数组长度进行判断了:
若是偶数,比如像3,4,3,4, 此时必有 4 - 3 = 1,即 偶数的时候应该检验1
而若是奇数,比如像3,4,3, 此时必有 3 - 3 = 0, 即 奇数的时候应该检验0
所以我们使用(length - 1) % 2 来进行具体检验。
代码
class Solution {
public:
int alternatingSubarray(vector<int>& nums) {
int maxLen = -1, n = nums.size();
for (int i = 0; i < n - 1; i++){
for(int j = i+1; j < n; j++){
int length = j - i + 1;
if(nums[j] - nums[i] == (length - 1) % 2) //如果长度为奇数,应该差值为0; 如果长度为偶数,应该差值为1
{
maxLen = max(maxLen, length);
}
else break;
}
}
return maxLen;
}
};
2.2 单层循环
思路
整体省去了外部大循环,也就是回溯的起始位置。
通过对奇数和偶数情况判断省去了重复回溯的情况
我们已经知道子数组 nums[firstIndex,…,i−1]是满足交替子数组的条件的
1.对于索引从firstIndex+1,+3,+5,...情况,举个例子 原来:3,4,3,4,3,4,..., 现在从 4,3,4,3,.... 不满足 s1 = s0 + 1
2.对于索引从firstIndex+2,+4,+6,...情况,其实上是该子数组的子集,最终也将在nums[i]时结束,而且长度肯定是小于该子数组的,所以没必要讨论
综上所述,可以省去大量重复回溯
接下来我们讨论一下在nums[i]这里发生阻断的情况
- 情况是3,4,3,4,5,... ,这时候我们可以将位置回溯到i-1,并检测一下最大长度(这已经是一个交替子数组,长度为2),这里必须检测,因为后面会有i++,就是进行长度能否为3的检测了,若是不通过,这里为2的值也没有记录下来。
- 情况是3,4,3,4,6(非5),...,这时候直接回溯到索引i,然后开始继续检测即可。
代码
class Solution {
public:
int alternatingSubarray(vector<int>& nums) {
int res = -1;
int n = nums.size();
int firstIndex = 0;
for (int i = 1; i < n; i++) {
int length = i - firstIndex + 1;
if (nums[i] - nums[firstIndex] == (length - 1) % 2) {
res = max(res, length);
} else {
if (nums[i] - nums[i - 1] == 1) {
firstIndex = i - 1;
res = max(res, 2);
} else {
firstIndex = i;
}
}
}
return res;
}
};