3350. 检测相邻递增子数组 II

问题

给你一个由 n 个整数组成的数组 nums ,请你找出 k 的 最大值,使得存在 两个 相邻 且长度为 k 的 严格递增 子数组。具体来说,需要检查是否存在从下标 a 和 b (a < b) 开始的 两个 子数组,并满足下述全部条件:

这两个子数组 nums[a..a + k - 1] 和 nums[b..b + k - 1] 都是 严格递增 的。
这两个子数组必须是 相邻的,即 b = a + k。
返回 k 的 最大可能 值。

子数组 是数组中的一个连续 非空 的元素序列。

示例 1:
输入:nums = [2,5,7,8,9,2,3,4,3,1]

输出:3
解释:
从下标 2 开始的子数组是 [7, 8, 9],它是严格递增的。
从下标 5 开始的子数组是 [2, 3, 4],它也是严格递增的。
这两个子数组是相邻的,因此 3 是满足题目条件的 最大 k 值。

分析

代码

class Solution {
public:
    int res = 0;
    vector<int> q;
    bool check(int x) {
        int ll = 0, lr = x-1, rl = x, rr = 2*x-1;
        while(rr < q.size()) {
            bool flag = true;
            for (int i = ll+1; i <= lr; i++) {
                if (q[i] <= q[i-1]) {flag = false; break;}
            }
            if (!flag) {ll++, lr++, rl++, rr++;continue;}
            for (int i = rl+1; i <= rr; i++) {
                if (q[i] <= q[i-1]) {flag = false; break;}
            }
            if (flag) {return true;}
            ll++, lr++, rl++, rr++;
        }
        return false;
    }
    int maxIncreasingSubarrays(vector<int>& nums) {
        int r = nums.size() / 2 + 1;
        int l = 0;
        this->q = nums;
        while(l + 1 < r) {
            int mid = (l + r) >> 1;
            if (check(mid)) {
                l = mid;
            } else {
                r = mid;
            }
        }
        res = l;
        return res;
    }
};

关于检查函数,这个复杂度过高,一个一个滑动,浪费时间。
猜想:滑动窗口可以使用双端队列高效管理。

参考:https://leetcode.cn/problems/adjacent-increasing-subarrays-detection-ii/solutions/2984708/er-fen-shuang-hua-chuang-by-huan-xin-27-juuk

class Solution {
public:
    int res = 0;
    vector<int> q;
    //可以这样,使用滑动窗口来做这个题,维护两个滑窗,然后判断每次
    //滑动的时候判断当前窗口的大小是否等于k,如果两个窗口都等于
    //k,那么说明可以构成连续的两个相邻严格递增子数组了 
    bool check(int x) {
        deque<int> q1, q2;
        for (int i = 0, j = x; j < q.size(); i++, j++) {
            if (q1.size() && q1.front() < i-x+1) {
                q1.pop_front();
            } if (q2.size() && q2.front() < j-x+1) {
                q2.pop_front();
            } while (q1.size() && q[q1.back()] >= q[i]) {
                q1.pop_back();
            } while (q2.size() && q[q2.back()] >= q[j]) {
                q2.pop_back();
            }
            q1.push_back(i); q2.push_back(j);
            if (q1.size() == x && q2.size() == x) {
                return true;
            }
        }
        return false;
    }
    int maxIncreasingSubarrays(vector<int>& nums) {
        int r = nums.size() / 2 + 1;
        int l = 0;
        this->q = nums;
        while(l + 1 < r) {
            int mid = (l + r) >> 1;
            if (check(mid)) {
                l = mid;
            } else {
                r = mid;
            }
        }
        res = l;
        return res;
    }
};
posted @ 2025-10-15 16:53  saulstavo  阅读(17)  评论(0)    收藏  举报