239.Sliding windows maximum

来源:互联网 发布:淘宝网电脑版登陆网址 编辑:程序博客网 时间:2024/06/06 03:29

Approach #1 Segment Tree [ Accepted ]

Algorithm

It is a RMQ question so we think about the segment tree.We query the Sliding window in O(LogN).

c++

class Solution {public:    int n;    vector<int> tree;    void InitTree(vector<int>& nums) {        if(nums.size()>0) {            n=nums.size();            tree.resize(n*2,0);            bulidTree(nums);        }    }    void bulidTree(vector<int>& nums) {        for(int i=n,j=0;i<2*n;i++,j++) {            tree[i]=nums[j];        }        for(int i=n-1;i>0;i--) {            tree[i]=max(tree[i*2],tree[i*2+1]);        }    }     int MaxOfRange(int left, int right) {        left+=n;        right+=n;        int Max=INT_MIN;        while(left<=right) {            if(left%2==1) {                Max=max(Max,tree[left]);                left++;            }            if(right%2==0) {                Max=max(Max,tree[right]);                right--;            }            left/=2;            right/=2;        }        return Max;    }    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        vector<int> ans;        if(nums.size()==0)return ans;         int start=0;        InitTree(nums);        while(start+k-1<nums.size()) {            ans.push_back(MaxOfRange(start,start+k-1));            start++;        }        return ans;    }};

Complexity Analysis

  • Time complexity : O(NLogN).

  • Space complexity : O(N).

Approach #2 Sparse Table [ Accepted ]

Algorithm

Because it is a RMQ question , so we can do with Sparse table .

c++

class Solution {public:    void ST(vector<int> & nums){        dp.resize( nums.size() ,  vector<int>(20,0) );        for( int i = 0; i<nums.size() ; i ++ ){            dp[i][0] = nums[i];        }        for( int j = 1 ; (1<<j) <=nums.size()  ; j++ ){            for( int i = 0 ; i +(1<<j)-1< nums.size() ; i ++) {                dp[i][j]  = max( dp[i][j-1]  , dp[i+(1<<(j-1))][j-1] );            }        }    }    int RMQ(int left ,  int right ){        int length =(int)(log( ( double )(right - left +1 ) ) /log(2.0) );        return max( dp[left][length] , dp[right - (1<<length) + 1 ][length] );    }    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        if(nums.size()==0)return ans;        ST(nums);        int start = 0;        while( start + k - 1 < nums.size() ){            ans.push_back( RMQ(start,start+k-1 ) ) ;            start++;        }        return ans ;    }private:    vector<vector<int>> dp;    vector<int> ans ;};

Complexity Analysis

  • Time complexity : O(NLogN).

  • Space complexity : O(NLogN).

Approach #3 Heap [ Accepted ]

Algorithm

We maintain a heap and refresh the maximum.

c++

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        if( nums.size() == 0) {return ans ;}        int i = 0 ;        while(i<k){            qlist.push(nums[i++]);        }        while(1){            ans.push_back( qlist.top() ) ;            if( i == nums.size() ){ break ; }            int start = nums[i-k] , end = nums[i++] ;            qlist.push(end);            hash[start] ++;            while( hash[qlist.top()] ) {                hash[qlist.top()]--;                qlist.pop();            }        }        return ans ;    }private:    vector<int> ans;    priority_queue<int> qlist;    unordered_map<int,int> hash ;};

Complexity Analysis

  • Time complexity : O(NLogN).

  • Space complexity : O(K).

Approach #4 Double ended queue [ Accepted ]

Algorithm

We can do this problem with deque

  1. ensure the front is maximum;

  2. save the pos of nums[i];

  3. ensure the front in the sliding windows

  4. save the target to the ans

c++

class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        deque<int> q;        vector<int> ans ;        for( int i = 0 ; i< nums.size() ; i ++) {            //ensure the front is maximum;            while(q.size() && nums[i]>=nums[q.back()]){                q.pop_back();            }            //save the pos of nums[i];            q.push_back(i);            //ensure the front in the sliding windows            if( q.front()== i-k ){                q.pop_front();            }            //save the target to the vector <int> ans             if( i >= k - 1 ){                ans.push_back( nums[q.front()] );            }        }        return ans ;    }};

Complexity Analysis

  • Time complexity : O(N).

  • Space complexity : O(K).