温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用C++求滑动窗口最大值

发布时间:2022-01-19 10:16:10 来源:亿速云 阅读:186 作者:小新 栏目:大数据

这篇文章主要为大家展示了“如何使用C++求滑动窗口最大值”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用C++求滑动窗口最大值”这篇文章吧。

一、题目描述

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                 最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

示例 2:
输入:nums = [1], k = 1
输出:[1]

示例 3:
输入:nums = [1,-1], k = 1
输出:[1,-1]
提示:1 <= nums.length <= 10e5-10e4 <= nums[i] <= 10e41 <= k <= nums.length

二、题解

(1) 暴力遍历法

这种方法思路比较简单、直接:从左向右依次滑动窗口的过程中,计算每一次的最大值,存入ans中。

class Solution {
   
   
   public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {
   
   
   vector<int> ans;int max;for(int i=0; i<nums.size()-k+1; ++i){
   
   
   max = nums[i];for(int j=i; j<i+k; ++j){
   
   
   if(nums[j]>max)max = nums[j];}ans.push_back(max);}return ans;}};

这种方法时间复杂度O(nk),会超出时间限制,因此需要进行一些优化!

(2) 优先队列

对于本题,两个相邻(只差了一个位置)的滑动窗口,它们共用着 k-1 个元素,而只有 1个元素是变化的,我们可以根据这个特点进行优化。

优先队列priority_queue与普通队列queue的不同之处在于,它包含的最大值元素位于队首,因此这是一种非常合适解决此类问题的数据结构。

C++中,优先队列priority_queue类的具体用法可参见:【C++养成计划】队列 —— 快速上手STL queue类(Day13)

对于本题而言,具体步骤是:

  • 将数组 nums 的前 k 个元素放入优先队列中,并找出第一个窗口的最大值,存入ans中

  • 向右移动窗口时,把一个新的元素放入优先队列中,此时堆顶的元素就是堆中所有元素的最大值。

  • 根据最大元素的索引号判断:该元素是否属于该窗口内,从而删除不属于当前窗口的所有较大值。直到最大值属于当前的窗口,该值极为当前窗口的最大值。

class Solution {
   
   
   public:vector<int> maxSlidingWindow(vector<int>& nums, int k) {
   
   
   int n = nums.size();priority_queue<pair<int, int>> q;// 将数组 nums 的前 k 个元素放入优先队列中for (int i = 0; i < k; ++i) {
   
   
   q.emplace(nums[i], i);}vector<int> ans = {
   
   
   q.top().first};for (int i = k; i < n; ++i) {
   
   
   // 把一个新的元素放入优先队列中q.emplace(nums[i], i);while (q.top().second <= i - k) {
   
   
   // 如果优先队列的最大值不属于当前窗口,则删掉该最大值q.pop();}// 剩下的里面最大值即可ans.push_back(q.top().first);}return ans;}};

复杂度分析:

  • 时间复杂度:O(nlogn),其中 n 是数组 nums 的长度。由于将一个元素放入优先队列的时间复杂度为 O(logn),因此总时间复杂度为 O(nlogn)。

  • 空间复杂度:O(n),即为优先队列需要使用的空间。

注:这里所有的空间复杂度分析都不考虑返回的答案需要的 O(n) 空间,只计算额外的空间使用。

以上是“如何使用C++求滑动窗口最大值”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

c++
AI