974. 和可被 K 整除的子数组
C代码:滑动窗口
// 1、最长子数组 2、两个单调队列、求最大值-最小值,判断是否满足条件 3、满足记录长度
// 窗口移动条件:
int longestSubarray(int* nums, int numsSize, int limit){
int queMax[numsSize];
int queMin[numsSize];
int leftMax = 0, rightMax = 0;
int leftMin = 0, rightMin = 0;
int l = 0;
int ret = 0;
for (int r = 0; r < numsSize; ++r) {
while(leftMax < rightMax && queMax[rightMax - 1] < nums[r]) {
--rightMax;
}
while(leftMin < rightMin && queMin[rightMin - 1] > nums[r]) {
--rightMin;
}
queMax[rightMax++] = nums[r];
queMin[rightMin++] = nums[r]; // 滑动窗口核心:绝对值之差 > 限制,就该收缩窗口了,因为元素多了,需要减少元素
while (leftMax < rightMax && leftMin < rightMin && queMax[leftMax] - queMin[leftMin] > limit) {
if (nums[l] == queMin[leftMin]) {
leftMin++;
}
if (nums[l] == queMax[leftMax]) {
leftMax++;
}
l++; // 窗口内绝对值差 > 限制了,就只能窗口左端右移;右移的同时,如果nums[l]是窗口的最大值/最小值,就要将其移出队列;
} // 若不是,则忽略,因为不参与绝对值判断!
ret = fmax(ret, r - l + 1);
}
return ret;
}