您好,登录后才能下订单哦!
这篇文章主要为大家展示了“如何使用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
这种方法思路比较简单、直接:从左向右依次滑动窗口的过程中,计算每一次的最大值,存入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),会超出时间限制,因此需要进行一些优化!
对于本题,两个相邻(只差了一个位置)的滑动窗口,它们共用着 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++求滑动窗口最大值”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。