【剑指offer】滑动窗口的最大值
题目链接:滑动窗口的最大值
题意:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1},
题解:
1、首先想到的还是暴力。。。每次加入一个,判断一下当前的最大值。
2、这里正解应该是双端队列。参考了一下讨论区大佬的回答。
大概就是每次窗口里移走比当前出现值小的元素。保证最大值出现在队头。
判断滑动窗口是否包括数字,则是存储队列的下标。当某数字下标与当前数字的下标之差大于或者相等于size时,这个数字已经滑出,可以删除。
代码:
1 class Solution { 2 public: 3 vector<int> maxInWindows(const vector<int>& num, unsigned int size){ 4 vector<int> ans; 5 int len = num.size(); 6 if(len <=0 || size <= 0) return ans; 7 int start = 0; int end = size-1; 8 while(end < len){ 9 ans.push_back(getMax(start,end,num)); 10 start++;end++; 11 } 12 return ans; 13 } 14 int getMax(int start,int end ,const vector<int> &num){ 15 int max = num[start]; 16 for(int i = start+1 ; i <= end; i++){ 17 if(num[i] > max) max = num[i]; 18 } 19 return max; 20 } 21 }; 22 23 24 OR 25 26 27 class Solution { 28 public: 29 vector<int> maxInWindows(const vector<int>& num, unsigned int size){ 30 vector<int> ans; 31 deque<int> q; //存储num下标 32 int len = num.size(); 33 for(int i = 0; i < len ;i++){ 34 //弹出队尾比当前值小的元素 35 while(!q.empty() && num[q.back()] <= num[i]) 36 q.pop_back(); 37 //当前窗口移动,即移出队首元素的位置 38 if(!q.empty() && (i-q.front()+1 > size)) 39 q.pop_front(); 40 q.push_back(i); //加入滑动的下标 41 if(size && (i+1 >= size))//滑动的首地址下标大于size才写入。 42 ans.push_back(num[q.front()]); 43 } 44 return ans; 45 } 46 };