[滑动窗口] leetcode 239 Sliding Window Maximum

problem:https://leetcode.com/problems/sliding-window-maximum/

        解法一:使用平衡二叉树(map), 时间复杂度 :O(N * log K)

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        if (nums.size() == 0) return res;
        map<int,int> count;
        for (int i = 0; i < k; i++)
        {
            count[nums[i]]++;
        }
        res.push_back(count.rbegin()->first);
        for (int i = k; i < nums.size(); i++)
        {
            // erase
            count[nums[i - k]]--;
            if (count[nums[i - k]] == 0)
            {
                count.erase(nums[i - k]);
            }

            // insert
            count[nums[i]]++;

            res.push_back(count.rbegin()->first);
        }

        return res;
    }
};

        解法二:维护最大数据的下标,根据滑动窗口的移动更新下标。时间复杂度:平摊下接近O(N)

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        if (nums.size() == 0) return res;
        
        int maxnum = INT_MIN;
        int index;
        for (int i = 0; i < k; i++)
        {
            if (nums[i] > maxnum)
            {
                maxnum = nums[i];
                index = i;
            }
            maxnum = max(nums[i], maxnum);
        }
        res.push_back(maxnum);
        for (int i = k; i < nums.size(); i++)
        {
            if (nums[i] > maxnum)
            {
                maxnum = nums[i];
                index = i;
            }

            else if (i - k == index)
            {
                maxnum = INT_MIN;
                for (int j = index + 1; j <= i; j++)
                {
                    if (nums[j] > maxnum)
                    {
                        maxnum = nums[j];
                        index = j;
                    }
                }
            }

            res.push_back(maxnum);
        }

        return res;
    }
};

        解法三:单调队列。维护一个单调递减的队列,因为当最大的数据被移除后,我们总是希望找到第二大的数据,如果维持一个单调递减的队列,我们将队首移除后,新的队首自然就是第二大的。时间复杂度:平摊下接近O(N)

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> monoQueue;
        vector<int> ans;
        for (int i = 0; i < nums.size(); i++) 
        {
            if (!monoQueue.empty() && monoQueue.front() == i - k)
            {
                monoQueue.pop_front();
            }
            while (!monoQueue.empty() && nums[monoQueue.back()] < nums[i])
            {
                monoQueue.pop_back();
            }
            monoQueue.push_back(i);

            if (i >= k - 1)
            {
                ans.push_back(nums[monoQueue.front()]);
            }
        }
        return ans;
    }
};

 

:) 这个挺好的,记一下 https://leetcode.com/problems/shortest-subarray-with-sum-at-least-k/discuss/204290/Monotonic-Queue-Summary

posted @ 2019-07-29 16:32  fish1996  阅读(294)  评论(0)    收藏  举报