题目描述
给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{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}, {2,3,4,2,6,[2,5,1]}。
思路:利用双端队列。队列里保存当前窗口中可能是最大值的数。
1 class Solution { 2 public: 3 vector<int> maxInWindows(const vector<int>& num, unsigned int size) 4 { 5 int len = num.size(); //记录num的长度 6 deque<int> dq; //保存可能是最大值的索引(下标) 7 vector<int> res; 8 if (size == 0) //如果窗口大小为0,返回空 9 return res; 10 for (unsigned int i = 0; i < len; i++) { 11 //从后面弹出所有不大于num[i]的数,因为他们不可能是当前窗口的最大值。 12 while (!dq.empty() && (num[dq.back()] <= num[i])) { 13 dq.pop_back(); 14 } 15 //弹出队列中首元素脱离当前窗口的下标值。 16 while (!dq.empty() && (i - dq.front() + 1 > size)) { 17 dq.pop_front(); 18 } 19 //根据前两步,队首元素是当前窗口最大值的下标 20 dq.push_back(i); 21 if (!dq.empty() && (i + 1 >= size)) { // i >= size - 1时才开始保存窗口最大值 22 res.push_back(num[dq.front()]); 23 } 24 } 25 return res; 26 } 27 };