【每日刷题】滑动窗口最大值

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sd4567855/article/details/86481909

day19, 滑动窗口最大值

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

返回滑动窗口最大值。

示例:
输入: 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

注意:你可以假设 k 总是有效的,1 ≤ k ≤ 输入数组的大小,且输入数组不为空。

解答:为了达到线性时间,需要使用堆(优先队列)来实现。
首先,先将指针从数组头走到第一个滑动窗口大小处,期间,将所有的元素放入堆中,输出第一个最大的元素。随后,逐个遍历,如果最大元素在滑动窗口中,则将目前元素入堆,输出最大元素,向下走;否则,将所有在滑动窗口外的最大元素从堆中去除,之后输出最大元素,继续向下走。

代码:

vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        if( nums.size() == 0)
            return nums;
        priority_queue< pair<int,int> > notes;
        pair<int, int> record[nums.size()];
        vector<int> result;
        for( int i = 0; i <nums.size(); i++)
            record[i].first = nums[i], record[i].second = i;
        
        for( int i = 0; i < k && i < nums.size(); i++)
            notes.push( record[i]);
            
        result.push_back( notes.top().first);
        
        for( int i = k; i < nums.size(); i++){
            if( i - k < notes.top().second){//最大值在滑动窗口中
                notes.push( record[i]);
                result.push_back( notes.top().first);
            }
            else{
                while( !notes.empty() && notes.top().second <= i - k)
                    notes.pop();
                notes.push( record[i]);
                result.push_back( notes.top().first);
            }
        }
        
        return result;
    }

运行结果:image.png-25kB


我的微信公众号

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sd4567855/article/details/86481909