[LeetCode]239.Sliding Window Maximum,maximumgapleetcode

來源:互聯網
上載者:User

[LeetCode]239.Sliding Window Maximum,maximumgapleetcode

題目

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.

Therefore, return the max sliding window as [3,3,5,5,6,7].Note: You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.Follow up:Could you solve it in linear time?

思路

如果採用蠻力法,這個問題似乎不難解決:可以掃描每一個滑動視窗的所有數字並找出其中的最大值。如果滑動視窗的大小為k,需要O(k)時間才能找出滑動視窗裡的最大值。對於長度為n的輸入數組,這個演算法總的時間複雜度是O(nk)。
  實際上一個滑動視窗可以看成是一個隊列。當視窗滑動時,處於視窗的第一個數字被刪除,同時在視窗的末尾添加一個新的數字。這符合隊列的先進先出特性。如果能從隊列中找出它的最大數,這個問題也就解決了。
  我們實現了一個可以用O(1)時間得到最小值的棧。同樣,也可以用O(1)時間得到棧的最大值。同時我們討論了如何用兩個棧實現一個隊列。綜合這兩個問題的解決方案,我們發現如果把隊列用兩個棧實現,由於可以用O(1)時間得到棧中的最大值,那麼也就可以用O(1)時間得到隊列的最大值,因此總的時間複雜度也就降到了O(n)。 我們可以用這個方法來解決問題。不過這樣就相當於在一輪面試的時間內要做兩個面試題,時間未必夠用。再來看看有沒有其它的方法。
  下面換一種思路。我們並不把滑動視窗的每個數值都存入隊列中,而只把有可能成為滑動視窗最大值的數值存入到一個兩端開口的隊列。接著以輸入數字{2,3,4,2,6,2,5,1}為例一步分析。
  數組的第一個數字是2,把它存入隊列中。第二個數字是3.由於它比前一個數字2大,因此2不可能成為滑動視窗中的最大值。2先從隊列裡刪除,再把3存入到隊列中。此時隊列中只有一個數字3.針對第三個數字4的步驟類似,最終在隊列中只剩下一個數字4.此時滑動視窗中已經有3個數字,而它的最大值4位於隊列的頭部。
  接下來處理第四個數字2。2比隊列中的數字4小。當4滑出視窗之後2還是有可能成為滑動視窗的最大值,因此把2存入隊列的尾部。現在隊列中有兩個數字4和2,其中最大值4仍然位於隊列的頭部。
  下一個數字是6.由於它比隊列中已有的數字4和2都大,因此這時4和2已經不可能成為滑動視窗中的最大值。先把4和2從隊列中刪除,再把數字6存入隊列。這個時候最大值6仍然位於隊列的頭部。
  第六個數字是2.由於它比隊列中已有的數字6小,所以2也存入隊列的尾部。此時隊列中有兩個數字,其中最大值6位於隊列的頭部。
  接下來的數字是5.在隊列中已有的兩個數字6和2裡,2小於5,因此2不可能是一個滑動視窗的最大值,可以把它從隊列的尾部刪除。刪除數字2之後,再把數字5存入隊列。此時隊列裡剩下兩個數字6和5,其中位於隊列頭部的是最大值6.
  數組最後一個數字是1,把1存入隊列的尾部。注意到位於隊列頭部的數字6是數組的第5個數字,此時的滑動視窗已經不包括這個數字了,因此應該把數字6從隊列刪除。那麼怎麼知道滑動視窗是否包括一個數字?應該在隊列裡存入數字在數組裡的下標,而不是數值當一個數位下標與當前處理的數位下標之差大於或者等於滑動視窗的大小時,這個數字已經從滑動視窗中滑出,可以從隊列中刪除了。

代碼

/*---------------------------------------*   日期:2015-07-19*   作者:SJF0115*   題目: 239.Sliding Window Maximum*   網址:https://leetcode.com/problems/sliding-window-maximum/*   結果:AC*   來源:LeetCode*   部落格:-----------------------------------------*/#include <iostream>#include <vector>#include <deque>using namespace std;class Solution {public:    vector<int> maxSlidingWindow(vector<int>& nums, int k) {        vector<int> result;        int size = nums.size();        if(size <= 0 || k <= 0){            return result;        }//if        // 雙向隊列        deque<int> deque;        for(int i = 0;i < k-1;++i){            // 刪除小於等於當前元素的值 例如 4 2 1 5            while(!deque.empty() && nums[i] >= nums[deque.back()]){                deque.pop_back();            }//while            deque.push_back(i);        }//for        // 不足k個        if(size < k){            result.push_back(nums[deque.front()]);        }//if        for(int i = k-1;i < size;++i){            // 刪除小於等於當前元素的值            while(!deque.empty() && nums[i] >= nums[deque.back()]){                deque.pop_back();            }//while            // 不在滑動視窗之內            while(!deque.empty() && i - deque.front() >= k){                deque.pop_front();            }//while            deque.push_back(i);            result.push_back(nums[deque.front()]);        }//for        return result;    }};int main(){    Solution s;    int k = 3;    vector<int> vec = {4,1,3};//,-1,-2,-3,5,3,6,7    vector<int> result = s.maxSlidingWindow(vec,k);    for(int i = 0;i < result.size();++i){        cout<<result[i]<<" ";    }//for    cout<<endl;    return 0;}

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.