力扣滑动窗口(2)

94 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

剑指 Offer 59 - I. 滑动窗口的最大值

思路:

「单调队列」这种特殊的数据结构来辅助了,

代码:

class Solution {
private:
    deque<int> data;
    
public:
    void push(int n) {
        //队头要最大,这时如果发现比队头大则我把之前那些都踢出,然后把我这个数放在队头,反之我就放在队尾。
        while (!data.empty() && data.back() < n) {
            data.pop_back();
        }
        data.push_back(n);
    }

    int max() {
        return data.front();
    }

    void pop(int n) {
        if (!data.empty() && data.front() == n) {
            data.pop_front();
        }
    }
    //主要利用队列头来比较这个最大的值
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        Solution window;
        vector<int> res;
        for (int i = 0; i < nums.size(); i++) {
            if (i < k - 1) {                     
                //先放区间[0, k - 1)的数进去     (//先把窗口的前 k - 1 填满)
                window.push(nums[i]);
            }
            else {
                window.push(nums[i]);
                res.push_back(window.max());
                window.pop(nums[i - k + 1]);         //如果发现nums[i - k + 1] == que.front()就把它踢出去,因为不在下一个k长度区间范围内,反之不踢它
                // nums[i - k + 1] 就是窗口第一个元素 解释 :(就是如果我下一步就滑出了这个窗口,那么我就应该把窗口第一个元素踢出)
            }
        }return res;
    }
};

1658. 将 x 减到 0 的最小操作数

思路:

移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。如果可以将 x 恰好减到 0,返回最小操作数否则,返回 -1。**相当于找到一个和为 sum - x 的最长连续子数组。**利用滑动窗口来解决。

代码:

class Solution {
public:
    int minOperations(vector<int>& nums, int x) {
        int n = nums.size();
        int ans = -1, sum = 0;
        int sum1 = 0;
       for (int i = 0; i < n; i++) {
           sum1 += nums[i];
       }
       if (sum1 < x) return -1;
        x = sum1 - x;
        for (int i = 0, j = 0; j < n; j++) {
            sum += nums[j];
            while (sum > x) {
                sum -= nums[i++];
            }
            if (sum == x) {
            ans = max(ans, j - i + 1);}
        }
        return ans == -1 ? -1 : n - ans;
    }
};