Leetcode|Sliding Window Maximum(multiset,优先队列,双端队列和区间树的应用)
来源:互联网 发布:雨伞 淘宝 编辑:程序博客网 时间:2024/05/22 17:26
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.
For example,
Given nums = [1,3,-1,-3,5,3,6,7]
, and k = 3.
Window position Max--------------- -----[1 3 -1] -3 5 3 6 7 3 1 [3 -1 -3] 5 3 6 7 3 1 3 [-1 -3 5] 3 6 7 5 1 3 -1 [-3 5 3] 6 7 5 1 3 -1 -3 [5 3 6] 7 6 1 3 -1 -3 5 [3 6 7] 7
Therefore, return the max sliding window as [3,3,5,5,6,7]
.
1,暴力解法:最低效的时间复杂度O(k*(n-k+1));,
2,STL中的内置容器的排序功能。(O(n*logk))
为了熟悉STL,使用优先队列和nultiset来解决,虽然时间复杂度不是最优的。
//借助红黑树的排序方法,在leetcode击败15%的人,效率很低啦。
vector<int> maxSlidingWindow(vector<int>& nums, int k) {//利用multiset中红黑树的排序功能 时间复杂度O(nlogk) int n=nums.size(); vector<int> max; multiset<int> smax; for(int i=0;i<n;i++){ if(i>=k) smax.erase(smax.find(nums[i-k]));//每次删除过期的一个元素,每次都得对k个数重新排序 smax.insert(nums[i]); if(i>=k-1) max.push_back(*smax.rbegin());//找到排在最后的数,就是最大的 } return max; }//借助STL的heap操作,击败了20%l的leetcoder。
vector<int> maxSlidingWindow(vector<int>& nums, int k) {//优先队列是一种配接器,底层是vector int n=nums.size(); vector<int> max; priority_queue<pair<int,int>> qmax; for(int i=0;i<n;i++){ while(!qmax.empty()&&qmax.top().second<=i-k){ qmax.pop(); } qmax.push(make_pair(nums[i],i)); if(i>=k-1) max.push_back(qmax.top().first); } return max; }
3,线段树(时间复杂度O(n*log(k)) 击败了26%的leetcoder.
线段树节点的三个数值元素为:start,end,max(记录区间的最大值),是以一个vector作为底层容器实现。
class Solution {public: vector<int> maxSlidingWindow(vector<int>& nums, int k) { int n=nums.size(); vector<int> res; if(k<=0||n==0||k>n) return res; SegmentTreeNode *root=build_segmentTree(0,k-1,nums); res.push_back(root->max); for(int i=k;i<n;i++){ modify(i%k,nums[i],root); res.push_back(root->max); } return res; }private: struct SegmentTreeNode{ int start,end,max; SegmentTreeNode *left,*right; SegmentTreeNode(int x,int y,int m):start(x),end(y),max(m),left(NULL),right(NULL){ } }; SegmentTreeNode* build_segmentTree(int start,int end,vector<int>& a){ if(start>end||a.size()==0||end>=a.size()) return NULL; SegmentTreeNode* root=new SegmentTreeNode(start,end,a[start]); if(start==end) return root; int mid=(start+end)/2; root->left=build_segmentTree(start,mid,a); root->right=build_segmentTree(mid+1,end,a); root->max=max(root->left->max,root->right->max); return root; } void modify(int dot,int newval,SegmentTreeNode* root){ if(dot<root->start||dot>root->end) return; if(root->start==root->end){ root->max=newval; return; } int mid=(root->start+root->end)/2; if(dot<=mid) modify(dot,newval,root->left); else modify(dot,newval,root->right); root->max=max(root->left->max,root->right->max); } };
4,,最优解O(n):双端队列 击败50%leetcoder
deque来存储下标值,这样可以获得元素大小和位置两组信息。队列元素个数永远小于等于k,从大到小排序。击败50%的leetcoder
vector<int> maxSlidingWindow(vector<int>& nums, int k) { int n=nums.size(); vector<int> max; deque<int> qmax; for(int i=0;i<n;i++){ while(!qmax.empty()&&nums[qmax.back()]<=nums[i]){//队尾的值实时更新 qmax.pop_back(); } qmax.push_back(i); if(qmax.front()==i-k){//更新过期的队首 qmax.pop_front(); } if(i>=k-1){ max.push_back(nums[qmax.front()]); } } return max; }
0 0
- Leetcode|Sliding Window Maximum(multiset,优先队列,双端队列和区间树的应用)
- leetcode 239. Sliding Window Maximum 滑动窗口最大值Maximum + 优先级队列 + multiset
- leetcode 239. Sliding Window Maximum 双端队列 滑动窗口最大值
- poj2823 Sliding Window (优先队列)
- POJ2823 sliding window 优先队列
- [LeetCode 239] Sliding Window Maximum (Queap/队列快速求最大值)
- POJ--2823[Sliding Window] 线段树或优先队列
- POJ2823 Sliding Window(线段树 ST算法 优先队列)
- POJ 2823 Sliding Window(优先队列)
- POJ 2823 Sliding Window(优先队列)
- POJ 2823 Sliding Window(优先队列)
- POJ2823 Sliding Window【双端队列】
- POJ-2823--Sliding Window--双端队列实现单调队列
- Sliding Window poj 单调队列的简单应用
- POJ2823 Sliding Window (单调队列的基本应用)
- LeetCode Sliding Window Maximum 滑动窗口(双向链表实现队列效果)
- leetcode Sliding Window Maximum
- [LeetCode]Sliding Window Maximum
- iOS笔试知识点集锦
- 数组线性表ArrayList的内部实现
- 数据结构在软件编程中的地位
- Robust Visual Tracking via Convolutional Networks 阅读笔记
- swift 代码笔记3
- Leetcode|Sliding Window Maximum(multiset,优先队列,双端队列和区间树的应用)
- leetcode_Maximum Subarray _medium(最大子数组的和)
- LeetCode || Valid Anagram
- 给定n个数,要求比较次数1.5n同时找出最大值和最小值
- ActionScript 3.0 学习(十) AS3 模拟转盘抽奖小程序
- glCleatDepth
- 华为2016校招机试题
- Eclipse集成javah
- 黑马程序员——CSS