3349. 检测相邻递增子数组 I——单调队列
题目
给你一个由 n 个整数组成的数组 nums 和一个整数 k,请你确定是否存在 两个 相邻 且长度为 k 的 严格递增 子数组。具体来说,需要检查是否存在从下标 a 和 b (a < b) 开始的 两个 子数组,并满足下述全部条件:
这两个子数组 nums[a..a + k - 1] 和 nums[b..b + k - 1] 都是 严格递增 的。
这两个子数组必须是 相邻的,即 b = a + k。
如果可以找到这样的 两个 子数组,请返回 true;否则返回 false。
子数组 是数组中的一个连续 非空 的元素序列。
示例 1:
输入:nums = [2,5,7,8,9,2,3,4,3,1], k = 3
输出:true
解释:
从下标 2 开始的子数组为 [7, 8, 9],它是严格递增的。
从下标 5 开始的子数组为 [2, 3, 4],它也是严格递增的。
两个子数组是相邻的,因此结果为 true。
分析
解法参考:https://leetcode.cn/problems/adjacent-increasing-subarrays-detection-ii/solutions/2984708/er-fen-shuang-hua-chuang-by-huan-xin-27-juuk
使用双端队列,front用来固定窗口长度(及时删去最早添加的超过窗长的元素),back用来将deque调整为单增队列。最终,如果q1和q2的长度都为k,则返回true,否则返回false。当然,要在每次循环后判断是否已经满足题目要求。
代码
class Solution {
public:
bool hasIncreasingSubarrays(vector<int>& nums, int k) {
deque<int> q1, q2;
int n = nums.size();
for (int l = 0, r = k; r < n; ) {
// 使用队列作为窗口,那么要限制窗口长度,删去最早添加的超过长度的元素。由于一次只添加一个,所以用if即可。
if (q1.size() && l-q1.front()+1 > k) {
q1.pop_front();
} if (q2.size() && r-q2.front()+1 > k) {
q2.pop_front();
// 队列看成单调队列
} while (q1.size() && nums[q1.back()] >= nums[l]) {
q1.pop_back();
} while (q2.size() && nums[q2.back()] >= nums[r]) {
q2.pop_back();
}
// 窗口长度内,单调队列,如果队列元素==题目窗口长度,则true
q1.push_back(l); q2.push_back(r);
l++; r++;
if (q1.size() == k && q2.size() == k) {return true;}
}
return false;
}
};

浙公网安备 33010602011771号