【原創】Sliding Window Maximum 解法分析


這道題是lintcode上的一道題,當然leetcode上同樣有。

本題需要尋找O(N)復雜度的算法。

 

解體思路比較有特點,所以容易想到參考 最小棧 的解題辦法。

但是最小棧用棧維護最小值很直觀,這道題是隊列,用什么數據結構好呢?也許看完暴力解會有點啟發。

 

但是思路還是一樣的,最大的要在最前面(直接獲取結果),小的值在后面保留下來(防止之后遍歷到的時候丟失數據)。並且某值出窗口的時候需要判斷是否要修改排在最前面的值。

 

一。暴力解

當然直觀看,暴力求解是 O(NK)的復雜度,大體的代碼如下:(寫的有點復雜費勁,主要當時是想通過vector構建頭尾可變動的隊列,發現STL里其實有就放棄了)

    vector<int> maxSlidingWindow(vector<int> &nums, int k) {
        // write your code here
        if (nums.empty()) return vector<int>();
        
        vector<int> maxVec;
        int maxV = INT_MIN;
        vector<int> res;
        for (int i = 0; i < k && i < nums.size(); i++) {
            if (maxV < nums[i])
                maxV = nums[i];
            maxVec.push_back(nums[i]);
        }
        res.push_back(maxV);
        for (int i = k; i < nums.size(); i++) {
            maxVec.push_back(nums[i]);
            maxVec.erase(maxVec.begin());
            if (nums[i - k] == maxV) {
                maxV = INT_MIN;
                for (int j = 0; j < maxVec.size(); j++)
                    if (maxV < maxVec[j])
                        maxV = maxVec[j];
            }
            if (nums[i] > maxV)
                maxV = nums[i];
            res.push_back(maxV);
        }
        
        return res;
    }

 

二。大頂堆

這個其實思路希望通過堆的構造還控制O(1)代價獲得最大元素,復雜度O(N * logK)

 

三。雙向隊列

終於到它了,其實對自己來說是想提醒自己一下STL里deque的存在。就像priority_queue一樣容易被忽略。

 

思路是維持一個不增序的雙向隊列,最大值在隊首(直接獲取結果)。隊列大小最多是窗口大小,由值出窗口控制。

最壞case時間復雜度為2N,所以O(N)復雜度。

    vector<int> maxSlidingWindow(vector<int> &nums, int k) {
        // write your code here
        deque<int> my_deq;
        vector<int> res;
        for (int i = 0; i < nums.size(); i++) {
            if (i - k >= 0) {  // 出隊列踢頭節點判斷
                if (!my_deq.empty() && nums[i - k] == my_deq.front())
                    my_deq.pop_front();
            }
       // 入隊列踢值判斷
while (!my_deq.empty() && nums[i] > my_deq.back()) my_deq.pop_back(); my_deq.push_back(nums[i]); if (i + 1 - k >= 0) // 窗口大小滿足判斷 res.push_back(my_deq.front()); } if (k > nums.size()) res.push_back(my_deq.front()); return res; }

 

轉載請注明出處~   http://www.cnblogs.com/xiaoboCSer/p/4895191.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM