您的位置:首页 > Web前端

剑指offer 65 - 滑动窗口的最大值

2015-05-28 21:34 337 查看
使用双向队列可以满足要求,滑动窗口的最大值总是保存在队列首部,队列里面的数据总是从大到小排列。当遇到比当前滑动窗口最大值更大的值时,则将队列清空,并将新的最大值插入到队列中。如果遇到的值比当前最大值小,则直接插入到队列尾部。每次移动的时候需要判断当前的最大值是否在有效范围,如果不在,则需要将其从队列中删除。由于每个元素最多进队和出队各一次,因此该算法时间复杂度为O(N)。

#include <iostream>
#include<vector>
#include<deque>
using namespace std;

vector<int> maxInWindows( const vector<int> &num,size_t size)
{
vector<int> maxInWindows;
if(num.size()>=size && size>=1) //此处size>=1
{
deque<int> index;
for(int i=0;i<size;i++) //前N个数中只留取一个最大值
{
while(!index.empty() && num[i]>=num[index.back()])
index.pop_back();
index.push_back(i);
}

for(int i = size ;i<num.size();i++)
{
maxInWindows.push_back(num[index.front()]);

while(!index.empty() && num[i]>=num[index.back()]) //尾部删除 >=
index.pop_back();
if( !index.empty() && (i-size)>= index.front() ) //首部删除
index.pop_front();

index.push_back(i);
}

maxInWindows.push_back(num[index.front()]);
}
return maxInWindows;
}

void Test(char* testName, const vector<int>& num, unsigned int size, const vector<int>& expected)
{
if(testName != NULL)
printf("%s begins: ", testName);

vector<int> result = maxInWindows(num, size);

vector<int>::const_iterator iterResult = result.begin();
vector<int>::const_iterator iterExpected = expected.begin();
while(iterResult < result.end() && iterExpected < expected.end())
{
if(*iterResult != *iterExpected)
break;

++iterResult;
++iterExpected;
}

if(iterResult == result.end() && iterExpected == expected.end())
printf("Passed.\n");
else
printf("FAILED.\n");
}

void Test1()
{
int num[] = {2, 3, 4, 2, 6, 2, 5, 1};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {4, 4, 6, 6, 6, 5};
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int));

unsigned int size = 3;

Test("Test1", vecNumbers, size, vecExpected);
}

void Test2()
{
int num[] = {1, 3, -1, -3, 5, 3, 6, 7};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {3, 3, 5, 5, 6, 7};
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int));

unsigned int size = 3;

Test("Test2", vecNumbers, size, vecExpected);
}

// increasingly sorted
void Test3()
{
int num[] = {1, 3, 5, 7, 9, 11, 13, 15};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {7, 9, 11, 13, 15};
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int));

unsigned int size = 4;

Test("Test3", vecNumbers, size, vecExpected);
}

// decreasingly sorted
void Test4()
{
int num[] = {16, 14, 12, 10, 8, 6, 4};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {16, 14, 12};
vector<int> vecExpected(expected, expected + siz
4000
eof(expected) / sizeof(int));

unsigned int size = 5;

Test("Test4", vecNumbers, size, vecExpected);
}

// size of sliding windows is 1
void Test5()
{
int num[] = {10, 14, 12, 11};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {10, 14, 12, 11};
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int));

unsigned int size = 1;

Test("Test5", vecNumbers, size, vecExpected);
}

// size of sliding windows is same as the array length
void Test6()
{
int num[] = {10, 14, 12, 11};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

int expected[] = {14};
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int));

unsigned int size = 4;

Test("Test6", vecNumbers, size, vecExpected);
}

// size of sliding windows is 0
void Test7()
{
int num[] = {10, 14, 12, 11};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

vector<int> vecExpected;

unsigned int size = 0;

Test("Test7", vecNumbers, size, vecExpected);
}

// size of sliding windows is greater than the array length
void Test8()
{
int num[] = {10, 14, 12, 11};
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int));

vector<int> vecExpected;

unsigned int size = 5;

Test("Test8", vecNumbers, size, vecExpected);
}

int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: