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]这里发生阻断的情况

  1. 情况是3,4,3,4,5,... ,这时候我们可以将位置回溯到i-1,并检测一下最大长度(这已经是一个交替子数组,长度为2),这里必须检测,因为后面会有i++,就是进行长度能否为3的检测了,若是不通过,这里为2的值也没有记录下来。
  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;
    }
};
posted @ 2024-01-23 01:10  DawnTraveler  阅读(25)  评论(0编辑  收藏  举报