由于之前看了牛客网的数据结构和算法的课程知道了左神,现在顺便就买了他的书做做题吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。
第一章 栈和队列
第一题:生成窗口最大值数组
有一个整型数组arr和一个大小为w的窗口从数组的最左边滑到最右边,窗口每次向右边滑一个位置。
例如,数组为【4,3,5,4,3,3,6,7】,窗口大小为3时:
窗口数组 最大值
[4 3 5] 4 3 3 6 7 5
4 [3 5 4] 3 3 6 7 5
4 3 [5 4 3] 3 6 7 5
4 3 5 [4 3 3] 6 7 4
4 3 5 4 [3 3 6] 7 6
4 3 5 4 3 [3 6 7] 7
如果数组长度为n,窗口大小为w,则一共产生n-w+1个窗口的最大值。
请功能实现一个函数,
输入:整型数组arr,窗口大小为w;
输出:一个长度为n-w+1的数组res,res【i】表示每一种窗口状态下的最大值。
//#include "stdafx.h"
//#include <iostream>
//#include <deque>
//using namespace std;
void getMaxWindow(int arr[],int len,int w){
deque<int> qmax;
for (int i=0;i<len;++i)
{
if (qmax.empty()||arr[i]<arr[qmax.back()])//调试一直不对是因为我把qmax里面装的当成了int数,其实是index,后来在qmax.back外面加了arr[]数据才对
{
qmax.push_back(i);
}
else{
while(!qmax.empty()&&arr[i]>=qmax.back())//一开始报错是因为while循环里的两个条件位置反了,没有先判断qmax是否为空,故报错
qmax.pop_back();
qmax.push_back(i);
}
if (qmax.front()==i-w)
{
qmax.pop_front();
}
if (i>=w-1)
{
cout<<arr[qmax.front()]<<" ";
}
}
}
//int _tmain(int argc, _TCHAR* argv[])
//{
// int arr[8]={4,3,5,4,3,3,6,7};
// getMaxWindow(arr,8,3);
// return 0;
//}
//假设数组长度为N,窗口大小为W,如果做出时间复杂度为O(NxW)的解法是不能让面试官满意的,本题要求面试者想出时间复杂度为O(N)的实现。
//本题的关键在于利用双端队列来实现窗口最大值的更新。首先生成双端队列qmax,qmax中存放数组arr中的下标。
//如果qmax为空,直接插入i。
//如果qmax不为空,则获取qmax队尾的坐标,记为j。
//如果a[j]>a[i],说明队尾的值比他数组大,则直接插入队列。
//如果a[j]<=a[i],需要把j从qmax弹出,然后会到第二步,再决定插入的策略。
//过期计算:如果qmax队头的下标等于i-w,说明过期,直接弹出。
//计算res值,当i-w>=0的时候就可以记录res的值了。