queue中存储当前可能成为sliding window 里的最大值,所以要把queue中所有小于当前元素的值都pop。
方法一:暴力
std::max_element is defined inside the header file and it returns an iterator(pointer)指针 pointing to the element with the largest value in the range [first, last). If more than one element satisfies the condition of being the largest, the iterator returned points to the first of such elements.
// C++ program to demonstrate the use of std::max_element #include <iostream> #include <algorithm> using namespace std; int main() { int v[] = { 'a', 'c', 'k', 'd', 'e', 'f', 'h' }; // Finding the maximum value between the first and the // fourth element int* i1; i1 = std::max_element(v, v + 4); cout << char(*i1) << " "; return 0; }
class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { if(nums.empty()) return {}; vector<int> ans; for(int i=0; i<nums.size()-k+1; ++i){ //计算次数 ans.push_back(*max_element(nums.begin()+i, nums.begin()+i+k)); } return ans; } };
方法二:
Multisets are a type of associative containers similar to set, with an exception that multiple elements can have same values.
- multiset::rbegin()– Returns a reverse iterator pointing to the last element in the multiset container.
std::equal_range is used to find the sub-range within a given range [first, last) that has all the elements equivalent to a given value. It returns the initial and the final bound of such a sub-range. This function requires the range to be sorted.
Return Value: It returns a pair object, whose member pair::first is an iterator to the lower bound of the subrange of equivalent values, and pair::second its upper bound. If there is no element equivalent to val, then both first and second point to the nearest element greater than val, or if val is greater than any other value, then both of them point to last.
注意equal_range 返回的是一个值为某个元素的一对迭代器,first指向区间开头,last指向区间末尾的下一个。
// C++ program to demonstrate the use of std::equal_range #include <iostream> #include <algorithm> #include <string> #include <vector> #include <functional> using namespace std; // Defining the BinaryFunction bool comp(int a, int b) { return (a > b); } int main() { vector<int> v = { 10, 10, 30, 30, 30, 100, 10, 300, 300, 70, 70, 80 }; // Declaring an iterator to store the // return value of std::equal_range std::pair<std::vector<int>::iterator, std::vector<int>::iterator> ip; // Sorting the vector v in descending order sort(v.begin(), v.end(), greater<int>()); // v becomes 300 300 100 80 70 70 30 30 30 10 10 10 // Using std::equal_range and comparing the elements // the element value is 10 ip = std::equal_range(v.begin(), v.begin() + 12, 10, comp); // Displaying the subrange bounds cout << "10 is present in the sorted vector from index " << (ip.first - v.begin()) << " till " << (ip.second - v.begin()); return 0; }
class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { vector<int> ans; multiset<int> window; //允许重复,从小到大排序 空间:O(k) for(int i=0; i<nums.size(); ++i){ window.insert(nums[i]); //O(logk) if(i>= k-1){ ans.push_back(*window.rbegin()); //取出window里的最大值 window.erase(window.equal_range(nums[i-k+1]).first); //元素第一次出现的地方 O(logk) //window.erase(nums[i-k+1]); //会把相同元素都删掉 } } return ans; } };
解法三:双端队列,可以在头尾插入和删除。
A function becomes const when const keyword is used in function’s declaration. The idea of const functions is not allow them to modify the object on which they are called. It is recommended practice to make as many functions const as possible so that accidental changes to objects are avoided.
#include<iostream> using namespace std; class Test { int value; public: Test(int v = 0) {value = v;} //构造函数 // We get compiler error if we add a line like "value = 100;" // in this function. int getValue() const {return value;} }; int main() { Test t(20); cout<<t.getValue(); return 0; }
Output:
20
注意当一个函数被声明为const时,它可以被任何类型的object调用;但是non-const 函数只能被non-const对象调用。
#include<iostream> using namespace std; class Test { int value; public: Test(int v = 0) {value = v;} int getValue() {return value;} }; int main() { const Test t; cout << t.getValue(); return 0; }
class monoQueue{ private: deque<int> data_; //双向链表 public: void push(int e){ //将所有比e小的元素都删掉 while(!data_.empty() && e>data_.back()) // 把data_中比e大的元素都pop出来 data_.pop_back(); //O(1) data_.push_back(e); //O(1) } void pop(){ data_.pop_front(); //O(1) } //最大的元素排在队列最前面 int max() const{ return data_.front(); } }; class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { monoQueue q; vector<int> ans; for(int i=0; i<nums.size(); ++i){ q.push(nums[i]); if(i >= k-1){ //当前window有足够多的元素了,即第一个window已经有了 ans.push_back(q.max()); if(nums[i-k+1] == q.max()) //因为窗口要后移,而当窗口的第一个元素 == data_中的最大元素时,从队列中pop掉 q.pop(); } } return ans; } };
不用类,直接将索引值存入deque中:
class Solution { public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { deque<int> index; vector<int> ans; for(int i=0; i<nums.size(); ++i){ while(!index.empty() && nums[i]>=nums[index.back()]) index.pop_back(); index.push_back(i); if(i>=k-1) //滑动窗口里的元素已经有k个了 ans.push_back(nums[index.front()]); if(i-k+1 >= index.front()) index.pop_front(); //window已经滑过了最大值 } return ans; } };