单调队列
- 经典用法:维持滑动窗口滑动过程中的最大值或最小值。最大值时,单调队列从头到尾降序
- 维持求解答案的可能性
- 单调队列里所有对象按照规定好的单调性组织
- 当某个对象从队尾进入单调队列时,会从队头或者队尾依次淘汰单调队列里,对后续求解答案没有帮助的对象
- 每个对象一旦弹出,可以结算其参与的答案,随后这个对象不再参与后续求解
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> maxSlidingWindow(vector<int> &nums, int k) { |
| vector<int> res; |
| |
| deque<int> dq; |
| |
| |
| for (int right = 0; right < k; ++right) { |
| |
| while (!dq.empty() && nums[dq.back()] <= nums[right]) |
| dq.pop_back(); |
| dq.emplace_back(right); |
| } |
| res.emplace_back(nums[dq.front()]); |
| |
| |
| for (int right = k, left = 1; right < nums.size(); ++right, left++) { |
| |
| while (!dq.empty() && nums[dq.back()] <= nums[right]) |
| dq.pop_back(); |
| |
| while (!dq.empty() && dq.front() < left) |
| dq.pop_front(); |
| |
| dq.emplace_back(right); |
| res.emplace_back(nums[dq.front()]); |
| } |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| bool withinLimit(vector<int> &nums, deque<int> &max_dq, deque<int> &min_dq, int number, int limit) { |
| int maxVal = max_dq.empty() ? number : max(number, nums[max_dq.front()]); |
| int minVal = min_dq.empty() ? number : min(number, nums[min_dq.front()]); |
| return maxVal - minVal <= limit; |
| } |
| |
| int longestSubarray(vector<int> &nums, int limit) { |
| int res; |
| int len = nums.size(); |
| deque<int> max_dq; |
| deque<int> min_dq; |
| |
| for (int left = 0, right = 0; left < len; left++) { |
| |
| while (right < len && withinLimit(nums, max_dq, min_dq, nums[right], limit)) { |
| |
| while (!max_dq.empty() && nums[max_dq.back()] <= nums[right]) |
| max_dq.pop_back(); |
| while (!min_dq.empty() && nums[min_dq.back()] >= nums[right]) |
| min_dq.pop_back(); |
| max_dq.emplace_back(right); |
| min_dq.emplace_back(right); |
| right++; |
| } |
| |
| |
| res = max(res, right - left); |
| |
| |
| if (max_dq.front() == left) max_dq.pop_front(); |
| if (min_dq.front() == left) min_dq.pop_front(); |
| } |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| bool cmp(pair<int, int> p1, pair<int, int> p2) { |
| return p1.first < p2.first; |
| } |
| |
| bool ok(vector<pair<int, int>> &arr, deque<int> &maxDeque, deque<int> &minDeque, int limit) { |
| int maxVal = maxDeque.empty() ? 0 : arr[maxDeque.front()].second; |
| int minVal = minDeque.empty() ? 0 : arr[minDeque.front()].second; |
| return maxVal - minVal >= limit; |
| } |
| |
| int main() { |
| |
| int len, limit; |
| cin >> len >> limit; |
| vector<pair<int, int>> arr; |
| for (int i = 0, index, val; i < len; ++i) { |
| cin >> index >> val; |
| arr.emplace_back(make_pair(index, val)); |
| } |
| |
| sort(begin(arr), end(arr), cmp); |
| |
| deque<int> maxDeque; |
| deque<int> minDeque; |
| int res = 0x7fffffff; |
| |
| for (int left = 0, right = 0; left < len; ++left) { |
| while (right < len && !ok(arr, maxDeque, minDeque, limit)) { |
| while (!maxDeque.empty() && arr[maxDeque.back()].second <= arr[right].second) |
| maxDeque.pop_back(); |
| while (!minDeque.empty() && arr[minDeque.back()].second >= arr[right].second) |
| minDeque.pop_back(); |
| maxDeque.emplace_back(right); |
| minDeque.emplace_back(right); |
| right++; |
| } |
| if (ok(arr, maxDeque, minDeque, limit)) |
| res = min(res, arr[right - 1].first - arr[left].first); |
| |
| if (!maxDeque.empty() && maxDeque.front() == left) maxDeque.pop_front(); |
| if (!minDeque.empty() && minDeque.front() == left) minDeque.pop_front(); |
| } |
| res = res == 0x7fffffff ? -1 : res; |
| cout << res; |
| } |
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| int shortestSubarray(vector<int> &nums, int k) { |
| int len = nums.size() + 1; |
| |
| vector<long> sum(len, 0); |
| for (int i = 1; i < len; ++i) |
| sum[i] = sum[i - 1] + nums[i - 1]; |
| |
| |
| deque<int> min_dq; |
| int res = INT_MAX; |
| |
| for (int i = 0; i < len; ++i) { |
| while (!min_dq.empty() && sum[i] - sum[min_dq.front()] >= k) { |
| |
| res = min(res, i - min_dq.front()); |
| min_dq.pop_front(); |
| } |
| |
| |
| while (!min_dq.empty() && sum[min_dq.back()] >= sum[i]) |
| min_dq.pop_back(); |
| |
| min_dq.emplace_back(i); |
| } |
| return res == INT_MAX ? -1 : res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| int findMaxValueOfEquation(vector<vector<int>> &points, int k) { |
| |
| deque<pair<int, int>> maxDq; |
| int len = points.size(); |
| int res = INT_MIN; |
| |
| for (int i = 0, x, y; i < len; ++i) { |
| x = points[i][0]; |
| y = points[i][1]; |
| |
| while (!maxDq.empty() && (x - maxDq.front().first > k)) |
| maxDq.pop_front(); |
| if (!maxDq.empty()) |
| res = max(res, maxDq.front().second + y + x - maxDq.front().first); |
| |
| while (!maxDq.empty() && maxDq.back().second - maxDq.back().first <= y - x) |
| maxDq.pop_back(); |
| maxDq.emplace_back(make_pair(x, y)); |
| } |
| return res; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| #include <deque> |
| #include <algorithm> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| bool judge(vector<int> &tasks, vector<int> &workers, int pills, int strength, |
| int tl, int tr, int wl, int wr) { |
| deque<int> minDq; |
| |
| int cost = 0; |
| |
| for (int i = wl, j = tl; i <= wr; ++i) { |
| |
| while (j <= tr && tasks[j] <= workers[i]) { |
| minDq.emplace_back(j); |
| j++; |
| } |
| if (!minDq.empty() && tasks[minDq.front()] <= workers[i]) { |
| |
| minDq.pop_front(); |
| } else { |
| |
| while (j <= tr && tasks[j] <= workers[i] + strength) { |
| minDq.emplace_back(j); |
| j++; |
| } |
| if (minDq.empty()) { |
| |
| |
| return false; |
| } else { |
| |
| |
| minDq.pop_back(); |
| |
| cost++; |
| } |
| } |
| } |
| |
| return cost <= pills; |
| } |
| |
| int maxTaskAssign(vector<int> &tasks, vector<int> &workers, int pills, int strength) { |
| sort(begin(tasks), end(tasks)); |
| sort(begin(workers), end(workers)); |
| int tLen = tasks.size(); |
| int wLen = workers.size(); |
| |
| int left = 0; |
| int right = min(tLen, wLen); |
| int mid; |
| |
| |
| while (left <= right) { |
| |
| mid = left + ((right - left) >> 1); |
| |
| if (judge(tasks, workers, pills, strength, |
| 0, mid - 1, wLen - mid, wLen - 1)) |
| left = mid + 1; |
| else |
| right = mid - 1; |
| } |
| return right; |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18399183
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步