// 面試題59(一):滑動視窗的最大值
// 題目:給定一個數組和滑動視窗的大小,請找出所有滑動窗口裡的最大值。例如,
// 如果輸入陣列{2, 3, 4, 2, 6, 2, 5, 1}及滑動視窗的大小3,那麼一共存在6個
// 滑動視窗,它們的最大值分別為{4, 4, 6, 6, 6, 5}, #include <iostream>
#include <vector>
#include <deque> using namespace std; vector<int> maxInWindows(const vector<int>& num, unsigned int size)
{
vector<int> maxInWindows;
if (num.size() >= size && size >= )
{
deque<int> index; for (unsigned int i = ; i < size; ++i)//先找出第一個滑窗裡的最大值的座標,放入佇列頭
{
while (!index.empty() && num[i] >= num[index.back()])
index.pop_back(); index.push_back(i);
} for (unsigned int i = size; i < num.size(); ++i)//對之後的每個點
{
maxInWindows.push_back(num[index.front()]);//先把佇列頭放入maxInWindows while (!index.empty() && num[i] >= num[index.back()])//如果佇列不為空且當前點大於尾節點,就刪除尾節點,直到尾節點不小於當前節點
index.pop_back();
if (!index.empty() && index.front() <= (int)(i - size))//如果佇列不為空,且頭結點的位置小於當前位置減去滑窗長度,說明這個最大值不再滑窗內了,刪除
index.pop_front(); index.push_back(i);//插入當前點的座標
}
maxInWindows.push_back(num[index.front()]);//最後那個值沒在迴圈中插入maxInWindows,要額外寫一句
} return maxInWindows;
} // ====================測試程式碼====================
void Test(const char* testName, const vector<int>& num, unsigned int size, const vector<int>& expected)
{
if (testName != nullptr)
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[] = { , , , , , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { , , , , , };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test1", vecNumbers, size, vecExpected);
} void Test2()
{
int num[] = { , , -, -, , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { , , , , , };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test2", vecNumbers, size, vecExpected);
} // 輸入陣列單調遞增
void Test3()
{
int num[] = { , , , , , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { , , , , };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test3", vecNumbers, size, vecExpected);
} // 輸入陣列單調遞減
void Test4()
{
int num[] = { , , , , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { , , };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test4", vecNumbers, size, vecExpected);
} // 滑動視窗的大小為1
void Test5()
{
int num[] = { , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { , , , };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test5", vecNumbers, size, vecExpected);
} // 滑動視窗的大小等於陣列的長度
void Test6()
{
int num[] = { , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); int expected[] = { };
vector<int> vecExpected(expected, expected + sizeof(expected) / sizeof(int)); unsigned int size = ; Test("Test6", vecNumbers, size, vecExpected);
} // 滑動視窗的大小為0
void Test7()
{
int num[] = { , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); vector<int> vecExpected; unsigned int size = ; Test("Test7", vecNumbers, size, vecExpected);
} // 滑動視窗的大小大於輸入陣列的長度
void Test8()
{
int num[] = { , , , };
vector<int> vecNumbers(num, num + sizeof(num) / sizeof(int)); vector<int> vecExpected; unsigned int size = ; Test("Test8", vecNumbers, size, vecExpected);
} // 輸入陣列為空
void Test9()
{
vector<int> vecNumbers;
vector<int> vecExpected; unsigned int size = ; Test("Test9", vecNumbers, size, vecExpected);
} int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
system("pause");
return ;
}