Description
给定一个整型数组arr和一个大小为w的窗口,窗口从数组最左边滑动到最右边,每次向右滑动一个位置,求出每一次滑动时窗口内最大元素的和。
Input
输入第一行为用例个数, 每个测试用例输入的第一行为数组,每一个元素使用空格隔开;第二行为窗口大小。
Output
输出每个测试用例结果。
Sample Input 1
1
4 3 5 4 3 3 6 7
3
Sample Output 1
32
思路
方法一
暴力法
窗口每次向右移动一位时,我们每次遍历窗口内的w个元素,然后求出此时窗口的最大值就可以了,用这种方法的时间复杂度是 O(wn)。代码如下:
#include <iostream>
#include <vector>
#include <string.h>
#include <string>
#include <deque>
#include <sstream>
using namespace std;
int main()
{
int t;
cin >> t;
for (int turn = 0; turn < t; turn++) {
int res = 0, len;
//将一组未知个数的数字读入一个数组a[]
string str;
cin.ignore();
getline(cin, str);
char aChar[90];
strcpy_s(aChar, str.c_str());
int a[999] = { 0 };
int index = 0, alen = -1;
while (aChar[index] != '\0') {
if (aChar[index] == ' ') {
index++;
}
else {
alen++;
a[alen] = aChar[index] - '0';
index++;
}
}
alen++;
/*另一种输入数组的方式,将数组输入vector
*stringstream ss;
*string str;
*int sin;
*cin.ignore();
*getline(cin, str);
*
*vector<int> a;
*ss << str;
*
*while (ss >> sin) {
* a.push_back(sin);
*}
*int aLen = a.size();
*/
cin >> len;
//题目变为对数组a中aLen个数字进行滑动查找
int sum = 0;
if (len < 1 || alen < len || alen<1) {
if (turn + 1 == t) {
printf("%d", res);
}
else {
printf("%d\n", res);
}
}
else {
int maxNum = 0;
for (int i = len - 1; i < alen; i++) {
maxNum = a[i];
for (int j = i - 1; j > i - len; j--) {
if (maxNum < a[j]) {
maxNum = a[j];
}
}
sum += maxNum;
}
res = sum;
if (turn + 1 == t) {
printf("%d", res);
}
else {
printf("%d\n", res);
}
}
}
return 0;
}
方法二
双向队列
使用双向队列,用来保存有可能是滑动窗口最大值的数组的下标。在存入一个数字的下标之前,首先要判断队列里已有数字是否小于待存入的数字。如果已有的数字小于待存入的数字,那么这些数字已经不可能是滑动窗口的最大值,因此需要在队列尾部删除(pop_back)。同时,如果队列头部的数字已经从窗口里滑出,那么滑出的数字也需要从队列的头部删除(pop_front)。
————————————————
版权声明:本文为CSDN博主「SCS199411」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/SCS199411/article/details/92414455
代码如下:
#include <iostream>
#include <vector>
#include <string.h>
#include <string>
#include <deque>
using namespace std;
int main()
{
int t;
cin >> t;
for (int turn = 0; turn < t; turn++) {
int res = 0, len;
//将一组未知个数的数字读入一个数组a[]
string str;
cin.ignore();
getline(cin, str);
char aChar[90];
strcpy(aChar, str.c_str());
vector<int> a;
int ind = 0, aLen = 0;
while (aChar[ind] != '\0') {
if (aChar[ind] == ' ') {
ind++;
}
else {
a.push_back(aChar[ind] - '0');
ind++;
}
}
aLen = a.size();
cin >> len;
//题目变为对数组a中aLen个数字进行滑动查找
int sum = 0;
if (a.empty() || len < 1 || len > aLen) {
if (turn + 1 == t) {
printf("%d", res);
}
else {
printf("%d\n", res);
}
}
else {
deque<int> dq;
for (int i = 0; i < len; ++i) {
while (!dq.empty() && a[i] >= a[dq.back()]) {
dq.pop_back();
}
dq.push_back(i);
}
for (int i = len; i < a.size(); ++i) {
res += a[dq.front()];
while (!dq.empty() && a[i] >= a[dq.back()])
dq.pop_back();
if (!dq.empty() && dq.front() <= (int)(i - len))
dq.pop_front();
dq.push_back(i);
}
res += a[dq.front()];
if (turn + 1 == t) {
printf("%d", res);
}
else {
printf("%d\n", res);
}
}
}
return 0;
}
转载自:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31561266/viewspace-2286701/
转载于:http://blog.itpub.net/31561266/viewspace-2286701/