【Hot100】239. 滑动窗口最大值

目录

  • 引言
  • 滑动窗口最大值
    • 暴力求解解题
    • 采用优先级队列优化

请添加图片描述

  • ‍♂️ 作者:海码007
  • 专栏:算法专栏
  • 标题:【Hot100】239. 滑动窗口最大值
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!

引言

滑动窗口最大值

  • 题目链接:
  • 做题状态:一开始想到一个暴力求解

暴力求解解题

暴力求解,这种时间复杂度有点高。

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if (nums.size() < k) return {};
        
        // 暴力计算,时间复杂度O(n*k)
        vector<int> result;
        for (int i = 0; i <= nums.size() - k; ++i)
        {
            int maxV = nums[i];
            for (int j = i; j < i + k; ++j)
            {
                maxV = max(maxV, nums[j]);
            }
            result.push_back(maxV);
        }
        return result;
    }
};

采用优先级队列优化

在最开始想着要维护一个最大值,想到了使用优先级队列适配器来实现,但是优先级队列只能移除队列顶部元素,不能给定一个值让其移除。所以当滑动窗口右移时,需要将左边界的值给移除掉。

所以如何直到队列中维护的数据是否处于滑动窗口中就很关键。这里使用优先级队列存储 pair {value: index} 根据index来判断是否处于滑动窗口的左边界的左侧。这是一个很巧妙的地方。

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if (nums.size() < k) return {};
        
        vector<int> result;
        priority_queue<pair<int, int>> pq;

        // 首先插入k个元素
        for (int i = 0; i < k; ++i)
        {
            pq.push({nums[i], i});
        }
        result.push_back(pq.top().first);

        // 遍历剩余的元素
        for (int i = k; i < nums.size(); ++i)
        {
            // 首先将当前滑动窗口右边界的元素插入到优先级队列中
            pq.push({nums[i], i});

            // 然后再判断当前优先级队列中的最大值是否是位于左边界的左侧,如果是则循环移除。
            // 因为可能需要移除多次,如果之前左侧数值小于最大值是不会被移除的,所以这里得循环移除
            while(pq.top().second < i - k + 1)
            {
                // index < i - k + 1 时说明当前index处于左边界左侧
                pq.pop();
            }

            // 再将最大值添加到结果中
            result.push_back(pq.top().first);
        }

        return result;
    }
};

你可能感兴趣的:(算法,算法,c++,Hot100,C++,hot100)