Priority Queue
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Sainnhe Park 2022-12-08 21:05:07 +08:00
parent 587076ab11
commit d7e65dd894
5 changed files with 141 additions and 0 deletions

View File

@ -0,0 +1,15 @@
#ifndef S0239_SLIDING_WINDOW_MAXIMUM_HPP
#define S0239_SLIDING_WINDOW_MAXIMUM_HPP
#include <vector>
#include <queue>
#include <utility>
using namespace std;
class S0239 {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k);
};
#endif

View File

@ -29,6 +29,7 @@
# 栈与队列 # 栈与队列
- [总结](./stack_and_queue.md)
- [用栈实现队列 && 用队列实现栈](./impl_stack_queue.md) - [用栈实现队列 && 用队列实现栈](./impl_stack_queue.md)
# 经典代码 # 经典代码

View File

@ -0,0 +1,70 @@
# 总结
## 栈
使用场景:
1. 需要先进后出的数据结构
2. 匹配问题
经典题目:
[20. 有效的括号](https://leetcode.cn/problems/valid-parentheses/)
[1047. 删除字符串中的所有相邻重复项](https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/)
## 队列
使用场景:
1. 先进先出的数据结构
2. 滑动窗口
### 变体:优先级队列
队列中的数据以 `<priority, value>` 的形式存储,每一个 `value` 都有一个 `priority`
当入队,我们根据 `priority` 将元素插入到队列的相应位置,队列中的元素总是按优先级升序或者降序排列。
```cpp
#include <iostream>
#include <queue>
#include <string>
#include <utility>
int main(int argc, const char *argv[]) {
// priority 为 int 类型value 为 std::string 类型
std::priority_queue<std::pair<int, std::string>> q;
// 写入元素
q.push(std::make_pair(3, "Microsoft"));
q.push(std::make_pair(1, "Surface"));
q.push(std::make_pair(2, "Apple"));
q.push(std::make_pair(4, "MacBook"));
// 访问顶部元素
std::cout << q.top().first << q.top().second << std::endl;
// 删除顶部元素
q.pop();
// 检查是否为空
if (q.empty()) {
std::cout << "Empty" << std::endl;
} else {
std::cout << "Not empty" << std::endl;
}
return 0;
}
```
输出:
```text
4MacBook
Not empty
```
优先队列用一般用堆来实现,具有 `O(log n)` 时间复杂度的插入元素性能,`O(n)` 的初始化构造的时间复杂度。
经典题目:[239. 滑动窗口最大值](https://leetcode.cn/problems/sliding-window-maximum/)
### 变体:单调队列
经典题目:[239. 滑动窗口最大值](https://leetcode.cn/problems/sliding-window-maximum/)

View File

@ -0,0 +1,36 @@
#include "s0239_sliding_window_maximum.hpp"
#include <utility>
// 优先级队列实现,每次操作的时间复杂度是 O(log(n)) ,因此总的时间复杂度是 O(n*log(n))
// 空间复杂度是 O(n)
vector<int> S0239::maxSlidingWindow(vector<int>& nums, int k) {
int len = nums.size();
if (len < 1 || k < 1) {
return {};
}
vector<int> result;
// 初始化优先级队列
priority_queue<pair<int, int>> q;
for (int i{0}; i < len && i < k; ++i) {
q.push(make_pair(nums[i], i));
}
if (k >= len) {
return {q.top().first};
} else {
result.push_back(q.top().first);
}
// 开始迭代
for (int i{1}; i + k - 1 < len; ++i) {
// 本轮迭代中滑动窗口的范围是 [i...i+k-1]
// 先把右边的元素放入队列
q.push(make_pair(nums[i + k - 1], i + k - 1));
// 确保队首元素在滑动窗口内
// 如果不在滑动窗口内,则弹出
while (q.top().second < i) {
q.pop();
}
// 现在队首元素就是滑动窗口内的最大值了
result.push_back(q.top().first);
}
return result;
}

View File

@ -0,0 +1,19 @@
#include "s0239_sliding_window_maximum.hpp"
#include <gtest/gtest.h>
TEST(Problem239, Case1) {
vector<int> nums{1, 3, -1, -3, 5, 3, 6, 7};
int k{3};
vector<int> expected{3, 3, 5, 5, 6, 7};
S0239 solution;
EXPECT_EQ(solution.maxSlidingWindow(nums, k), expected);
}
TEST(Problem239, Case2) {
vector<int> nums{1};
int k{1};
vector<int> expected{1};
S0239 solution;
EXPECT_EQ(solution.maxSlidingWindow(nums, k), expected);
}