难度困难159收藏分享切换为英文关注
通过次数
17,642
提交次数
41,311
给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例:
输入: nums =[1,3,-1,-3,5,3,6,7]
, 和 k = 3 输出:[3,3,5,5,6,7] 解释:
滑动窗口的位置 最大值 --------------- ----- [1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
提示:
你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小
(超时)
不看解析,想出来的暴力,每次通过滑动得到的新值去比较最大值,看是否比最大值大,如果大,压入辅助队列当中。中间可能会存在辅助队列为空的情况,这是重新计算模拟的原始队列,求最大值,再进行滑动比较。效率太低,最后一个测试用例无法通过。
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
// 示例:
// 输入: nums = [1, 3, -1, -3, 5, 3, 6, 7], 和 k = 3
// 输出 : [3, 3, 5, 5, 6, 7]
// 解释 :
//
// 滑动窗口的位置 最大值
// -------------- - ---- -
// [1 3 - 1] - 3 5 3 6 7 ------------------------>3
// 1[3 - 1 - 3] 5 3 6 7 ------------------------>3
// 1 3[-1 - 3 5] 3 6 7 ------------------------>5
// 1 3 - 1[-3 5 3] 6 7 ------------------------>5
// 1 3 - 1 - 3[5 3 6] 7 ------------------------>6
// 1 3 - 1 - 3 5[3 6 7] ------------------------>7
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
if (nums.empty()) {
return nums;
}
/* 记录滑动窗口每次的最大值 */
vector<int> m_MaxVec;
/* 存最大值 */
if (m_OriginQueue.empty()) {
maxVal = nums.front();
m_OriginQueue.push(nums.front());
m_MaxValQueue.push(nums.front());
}
vector<int>::iterator it;
for (it = nums.begin() + 1;
it != nums.begin() + k; it++) {
//cout << "it:" << *it << endl;
m_OriginQueue.push(*it);
/* 如果比原始值大则进行入队 */
if (*it >= maxVal) {
maxVal = *it;
m_MaxValQueue.push(*it);
}
}
/* 存取一次最大值 */
m_MaxVec.push_back(maxVal);
/* 滑动窗口 */
while (it != nums.end()) {
if (m_OriginQueue.front() == m_MaxValQueue.front()) {
cout<<"m_MaxValQueue front :"<<m_MaxValQueue.front()<<"-------MaxQueue size :" << m_MaxValQueue.size() << endl;
m_MaxValQueue.pop();
}
m_OriginQueue.pop();
/* 压入队列 */
m_OriginQueue.push(*it);
/* 考虑辅助队列(当前最大值队列)为空,此时重新遍历寻找最大值 */
if (m_MaxValQueue.empty()) {
vector<int>::iterator q_start = it - k + 1;
vector<int>::iterator q_end = it + 1;
int tempMax = *(q_start);
while (q_start != q_end) {
cout << "0000000000000000000000000--" << *q_start << endl;
if (*q_start > tempMax)
tempMax = *q_start;
q_start++;
}
m_MaxValQueue.push(tempMax);
cout << "0000000000000000000000000--" << tempMax << endl;
}
/* 或者压入队列元素比队尾元素大 */
else if (*it >= m_MaxValQueue.back()) {
m_MaxValQueue.push(*it);
}
cout << "or头部:" << m_OriginQueue.front() << endl;
cout << "or尾部:" << m_OriginQueue.back() << endl;
cout << "help头部:" << m_MaxValQueue.front() << endl;
cout << "help尾部:" << m_MaxValQueue.back() << endl;
cout << "Max:" << m_MaxValQueue.back() << endl;
m_MaxVec.push_back(m_MaxValQueue.back());
cout << endl;
it++;
}
return m_MaxVec;
}
private:
int maxVal;
queue<int> m_OriginQueue; //滑动窗口queue队列
queue<int> m_MaxValQueue; //存取最大值的队列
};
单调队列:
博主原文地址:https://leetcode-cn.com/problems/sliding-window-maximum/solution/dan-diao-dui-lie-by-labuladong/
#include <iostream>
#include <deque>
#include <vector>
using namespace std;
class Monotonic {
public:
void push(int n) {
while (!data.empty() && data.back() < n)
data.pop_back();
data.push_back(n);
}
int max() {
return data.front();
}
void pop(int n) {
if (!data.empty() && data.front() == n)
data.pop_front();
}
private:
deque<int> data;
};
class Solution {
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
Monotonic data;
vector<int> maxVec;
if (nums.empty())
return nums;
for (int i = 0; i < nums.size(); i++) {
if (i < k - 1) {
data.push(nums[i]);
}
else {
data.push(nums[i]);
maxVec.push_back(data.max());
data.pop(nums[i - k + 1]);
}
}
return maxVec;
}
};
int main() {
Solution *ps = new Solution();
int k = 0;
vector<int> test1 = {};
vector<int> test2 = { 1,3,-1,-3,5,3,6,7 };
vector<int> test3 = { 1,3,1,2,0,5 };
vector<int> test4 = { 1,-1 }; // k = 1;
vector<int> test5 = { -7,-8,7,5,7,1,6,0 };
vector<int>result = ps->maxSlidingWindow(test5, 4);
vector<int>::iterator it = result.begin();
while (it != result.end()) {
cout << " " << *it;
it++;
}
system("pause");
return 0;
}