应该是最经典的hard题之一了。
基本思路:
- 一个重要的性质:如果滑动窗口右端在j时,滑动窗口内部有num[i] <= num[j]且i < j,那么其实在j以及j的右端,num[i]已经完全失去了作用(相当于被j覆盖了),可以被删除。
- 使用双端队列deque维护非递增序列,队头为滑动窗口最大值,向前移动添加元素时与队尾比较,把队尾所有小于该元素的元素全部删去再添加该元素;移除末位元素时仅需与队头比较,如果是队头则删除。
class Solution { public: vector<int> maxInWindows(const vector<int>& num, unsigned int size) { vector<int> res; if (size == 0 || size > num.size()) return res; deque<int> dq; for (int i = 0; i < size; i++) { while (!dq.empty() && num[i] >= dq.back()) { dq.pop_back(); } dq.push_back(num[i]); } res.push_back(dq.front()); for (int i = size; i < num.size(); i++) { while (!dq.empty() && num[i] >= dq.back()) { dq.pop_back(); } dq.push_back(num[i]); if (dq.front() == num[i - size]) dq.pop_front(); res.push_back(dq.front()); } return res; } };