[Algo] 单调队列
1. 滑动窗口最大值
// 1. 滑动窗口最大值
// https://leetcode.cn/problems/sliding-window-maximum/description/
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
deque<int> dq;
vector<int> result;
for (int i = 0; i < k; i++)
{
while (!dq.empty() && nums[dq.back()] <= nums[i]) dq.pop_back();
dq.push_back(i);
}
result.push_back(nums[dq.front()]);
int r = k;
while (r <= nums.size() - 1)
{
while (!dq.empty() && nums[dq.back()] <= nums[r]) dq.pop_back();
dq.push_back(r);
if (dq.front() == r - k) dq.pop_front();
result.push_back(nums[dq.front()]);
r++;
}
return result;
}
2. 绝对差不超过限制的最长连续子数组
// 2. 绝对差不超过限制的最长连续子数组
// https://leetcode.cn/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit/
int longestSubarray(vector<int>& nums, int limit) {
deque<int> dq_max, dq_min;
dq_max.push_back(0);
dq_min.push_back(0);
int ans = 1;
for (int l = 0, r = 1; r < nums.size(); l++)
{
if (l == r)
{
dq_max.push_back(l);
dq_min.push_back(l);
r++;
}
int cur_max = nums[dq_max.front()];
int cur_min = nums[dq_min.front()];
while (r < nums.size() && nums[r] >= cur_max - limit && nums[r] <= cur_min + limit)
{
while (!dq_max.empty() && nums[dq_max.back()] <= nums[r]) dq_max.pop_back();
dq_max.push_back(r);
while (!dq_min.empty() && nums[dq_min.back()] >= nums[r]) dq_min.pop_back();
dq_min.push_back(r);
cur_max = nums[dq_max.front()];
cur_min = nums[dq_min.front()];
r++;
}
ans = max(ans, r - l);
if (dq_max.front() == l) dq_max.pop_front();
if (dq_min.front() == l) dq_min.pop_front();
}
return ans;
}
3. 和至少为K的最短子数组
// 3. 和至少为K的最短子数组
// https://leetcode.cn/problems/shortest-subarray-with-sum-at-least-k/description/
int shortestSubarray(vector<int>& nums, int k) {
vector<int> sum;
sum.resize(nums.size() + 1);
for (int i = 1; i < sum.size(); i++) sum[i] = sum[i - 1] + nums[i - 1];
deque<int> dq;
dq.push_back(0);
int ans = INT32_MAX;
for (int i = 1; i < sum.size(); i++)
{
while (!dq.empty() && sum[i] - sum[dq.front()] >= k)
{
ans = min(ans, i - dq.front());
dq.pop_front();
}
while (!dq.empty() && sum[dq.back()] >= sum[i]) dq.pop_back();
dq.push_back(i);
}
return ans == INT32_MAX ? -1 : ans;
}