正常做法应该是双端队列,但是我最开始没想到,属于取巧了。我怎么做的就不多说了,代码会放在文末,具体说说标准做法。
双端队列
因为数据规模大,因此二重循环肯定不行。所以需要在一次遍历的过程中就找到每个窗口中的最大值和最小值。以最小值为例,首先创建双端队列(直接用deque),在遍历的过程中将当前遍历到的数入队,之后只要入队的元素比当前队列中队头的数小,则让队列中所有元素出队,将当前的数放到队头。这样队头元素只有在遇到比他小的数才更新,意味着队头元素永远是窗口中的最小值。
此外,还要注意队列溢出的情况。需要在队列元素个数等于k的时候将队头元素抛出,直到队头元素是当前队列中的最小值。
代码如下:
#include <iostream>
#include <deque>
using namespace std;
int a[100000000];
int b[100000000];
int c[100000000];
int main()
{
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
deque<int> q1, q2;
//找最小值
for (int i = 0; i < n; i++)
{
if (i==0)
{
q1.push_back(a[i]);
continue;
}
if (q1.front() > a[i])
{
while (!q1.empty())
{
q1.pop_front();
}
}
q1.push_back(a[i]);
if (i == n - 1 && i >= k - 1)
{
cout << q1.front() << endl;
}
else if(i != n - 1 && i >= k - 1)
{
cout << q1.front() << " ";
}
if (q1.size() == k)
{
q1.pop_front();
int nmin = q1.front();
for (int j = i - k + 2;j<=i;j++)
{
nmin = min(nmin, a[j]);
}
while (q1.front() !=nmin)
{
q1.pop_front();
}
}
}
//找最大值
for (int i = 0; i < n; i++)
{
if (i == 0)
{
q2.push_back(a[i]);
continue;
}
if (q2.front() < a[i])
{
while (!q2.empty())
{
q2.pop_front();
}
}
q2.push_back(a[i]);
if (i == n - 1 && i >= k - 1)
{
cout << q2.front() << endl;
}
else if (i != n - 1 && i >= k - 1)
{
cout << q2.front() << " ";
}
if (q2.size() == k)
{
q2.pop_front();
int nmax = q2.front();
for (int j = i - k + 2; j <= i; j++)
{
nmax = max(nmax, a[j]);
}
while (q2.front() != nmax)
{
q2.pop_front();
}
}
}
}
本人硬想想出来的方法如下:
#include <iostream>
#include <string>
using namespace std;
int a[1000000] = { 0 };
int b[1000000] = { 0 };
int main()
{
int n, k;
cin >> n >> k;
int s=0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
int nmax = a[0];
int nmin = a[0];
for (int i = 0; i < n; i++)
{
nmax = max(nmax, a[i]);
nmin = min(nmin, a[i]);
if (i >= k-1)
{
b[s] = nmax;
if (i == n-1)
{
cout << nmin << endl;
}
else
{
cout << nmin << " ";
}
//
if (nmax == a[i-k+1])
{
nmax = a[i - k + 2];
for (int j = i - k + 2; j <= i; j++)
{
nmax = max(nmax, a[j]);
}
}
else if (nmin == a[i - k + 1])
{
nmin = a[i - k + 2];
for (int j = i - k + 2; j <= i; j++)
{
nmin = min(nmin, a[j]);
}
}
s++;
}
}
for (int i = 0; i < n - k+1; i++)
{
if (i == n - k )
{
cout << b[i] << endl;
}
else
{
cout << b[i] << " ";
}
}
}



京公网安备 11010502036488号