2021.9.25 force buckle - maximum value of sliding window

Posted by onyx on Sat, 25 Sep 2021 04:14:05 +0200

Title Description:

Give you an integer array nums, with a size of   k   The sliding window moves from the leftmost side of the array to the rightmost side of the array. You can only see k in the sliding window   A number. The sliding window moves only one bit to the right at a time.

Returns the maximum value in the sliding window.

Method 1:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        deque<int> qnum;    //The queue for recording numbers. The numbers in the queue are in descending order
        deque<int> qindex;  //Record the subscript corresponding to each number in qnum
        vector<int> ans;
        int maxnum = INT_MIN;
        int maxindex = 0;
        for (int i = 0; i < k; i++)
        {
            if (maxnum < nums[i])
            {
                maxnum = nums[i];
                maxindex = i;
            }
        }
        qnum.push_back(maxnum);
        qindex.push_back(maxindex);
        ans.push_back(maxnum);
        for (int i = maxindex + 1; i < nums.size(); i++)
        {
            if (i - k >= qindex.front())        //Each time a sliding window moves, it should pop up if the first element in the queue is on the leftmost side of the previous window
            {
                qnum.pop_front();
                qindex.pop_front();
            }
            if (qnum.empty() || nums[i] <= qnum.back())     //If the queue is empty or num [i] is less than or equal to the end element of the queue, you can join the queue directly
            {
                qnum.push_back(nums[i]);
                qindex.push_back(i);
            }
            else                            //Otherwise, always pop up the number with the end of the queue less than num [i], and then join num [i] into the queue
            {
                while (!qnum.empty() && nums[i] > qnum.back())
                {
                    qnum.pop_back();
                    qindex.pop_back();
                }
                qnum.push_back(nums[i]);
                qindex.push_back(i);
            }
            if (i - k >= 0)
            {
                ans.push_back(qnum.front());
            }
        }
        return ans;
    }
};

The first time I wrote a difficult topic, I was a little excited. Although I knew in advance that it was the stack and queue related applications, I still wrote it myself after all.

My idea is to use a two-way queue qnum, and the numbers in the queue are arranged in descending order, so each time the window slides, the first element of the queue is the maximum value in the window; In addition, to determine whether a number will move out of the window when the window slides, another two-way queue qindex is used to record the subscripts corresponding to each number in qnum.

For how to update numbers in qnum:

① First, when the window moves, if the queue head element in qnum happens to be the leftmost number of the previous window, the number must be removed after the window moves, so both qnum and qindex pop up the queue head element

② After the window moves, a new number comes in. Because the number in the queue should be kept in descending order, if the new number is less than the element at the end of the queue, it will be directly added to the queue. Otherwise, the elements in the queue will pop up until they are empty or the element at the end of the queue is greater than the new number.

Method 2:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        priority_queue<pair<int, int>> p;
        for (int i = 0; i < k; i++)
        {
            p.emplace(nums[i], i);
        }
        vector<int> ans = { p.top().first };
        for (int i = k; i < nums.size(); i++)
        {
            while (!p.empty() && p.top().second <= i - k)
            {
                p.pop();
            }
            p.emplace(nums[i], i);
            ans.push_back(p.top().first);
        }
        return ans;
    }
};

From the official solution, I originally thought of using the priority queue, but I thought it was difficult to solve two problems: one is how to record subscripts at the same time, and the other is how to delete numbers that have been moved out of the window from the priority queue, so I didn't use it.

In fact, for the first question: you can use pair. The first element records numbers and the second element records subscripts

For the second question: don't rush to delete the element. Judge whether the element at the head of the team is no longer in the current window every time. If so, pop it up again.

Time complexity: O(nlogn), where n is the length of array nums. In the worst case, the elements in the array num are monotonically increasing, then all the elements are included in the final priority queue, and no elements are removed. Since the time complexity of putting an element into the priority queue is O(logn), the total time complexity is O(nlogn).

Space complexity: O(n), that is, the space required by the priority queue. All spatial complexity analyses here do not consider the O(n) space required for the returned answer, and only calculate the use of additional space.

Topics: leetcode