Maxwindow
对一个数组,保持一个滑动窗口,求出每个窗口内的最大值。使用一个从左到右由大到小的队列,每次从队列前端取的数就是窗口的最大值。 如果新进来的数破坏了大小,则不断从队尾弹出元素,直至保持了由大到小的属性(相等时也需要弹出)。
struct WindowMax
{
//求窗口的最大值,需要对队列维护一个信息,由大到小
//遇到相同元素取后进的,因为虽然一样大,但是后进的晚过期
int L{ -1 }, R{-1};//窗口的左右边界,R是窗口右边界的下一个位置
//L和R分别窗口左右的上一个和下一个元素
vector<int> nums;
deque<int> Max;//存放元素的下标
WindowMax(vector<int> n):nums(n),L(-1),R(0){}
//窗口增大
void AddFromRight() {
if (R == nums.size()) {
return;
}
while (!Max.empty() && Max.back() <= nums[R]) {
Max.pop_back();
}
Max.push_back(R);
R++;
}
//窗口减小,如果窗口左边界跨过了最大值队列,最大值队列的相对应小标弹出
void RemoveFromLeft() {
if (L > R - 1) {//L>=R
return;
}
L++;
//L是窗口左边界的上一个位置
if (L == Max.front()) {
Max.pop_front();
}
}
int GetMax() {
if (!Max.empty()) {
return nums[Max.front()];
}
return INT_MIN;
}
};
``` c++ "指定窗口大小时,求每个窗口的最大值" vector getMax(vector& nums, int k) { if (nums.empty() || knums.size()) { return vector {}; } //窗口大小为k deque Max; vector result(nums.size() - k + 1); int index{ 0 }; for (auto i = 0; i < (int)nums.size(); ++i) { //处理每个元素,如果破坏了队列的大小结构 while (!Max.empty() && Max.back() <= nums[i]) { //从队尾弹出元素 Max.pop_back(); } Max.push_back(i); //来到一个新位置,需要处理过期窗口的过期元素,处理队列中的过期最大值 if (Max.front() == i - k) { Max.pop_front(); } //窗口形成后,每一轮都会产生一个最大值 if (i >= k - 1) { result[index++] = nums[Max.front()]; } } return std::move(result);
}
```
Last updated
Was this helpful?