滑动窗口的最大值

题目描述:

给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3,那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。

思路:

双端队列解决该问题,用队列开头控制窗口大小,如果窗口大小大于等于窗口大小时,则删除队列开头元素,而对于队列尾端用于与输入数据作比较,如果大于队列尾端元素,则将尾端元素抛掉,直到当前元素小于等于尾端元素为止,这样便能够保证双端队列开头元素值肯定是最大。下面用表格对题目中数组按照上述思路作一个呈现:

数组索引插入数据滑动窗口队列中数据(程序中使用的是数据索引)当前最大值
0222 
132、33 
242、3、44(大于3)4
323、4、24、2(小于4)4
464、2、66(大于4、2)6
522、6、26、2(小于6)6
656、2、56、5(大于2)6
712、5、15、1(删除6,因为已经不在窗口中)5

代码:

class solution
{
	public:
		vector<int> MaxNums(vector<int> data,int size)
		{
			
			deque<int> dataIndex;
			vector<int> result;
			/*先输入开头size个数据*/
			for(int i=0;i<size;i++)
			{
				while(!dataIndex.empty()&&data[i]>=data[dataIndex.back()])
				{
					dataIndex.pop_back();
				}
				dataIndex.push_back(data[i]);
			}
			result.push_back(data[dataIndex.front()]);
			/*从第size个数据开始往后遍历*/
			for(int i=size;i<data.length();i++)
			{
				/*当遍历到的数据比双端队列尾的数据大于等于时,抛掉双端队列尾端数据,直到双端队列开头数据是最大值*/
				while(!dataIndex.empty()&&data[i]>=data[dataIndex.back()])
				{
					dataIndex.pop_back();
				}
				/*当前的索引与双端队列开头数据索引之差大于等于size时,说明队列开头数据已经不在窗口中*/
				if((i-dataIndex.front)>=size)
				{
					dataIndex.pop_front();
				}
				dataIndex.push_back(i);
				result.push_back(data[dataIndex.front()]);
			}
			
			return result;
		}
}

代码2:

class Solution {
public:
    vector<int> maxInWindows(const vector<int>& num, unsigned int size)
    {
        int len = num.size();
        vector<int> result;
        if(len < size||size==0)
            return result;
        for(int i=0; i<=len-size; i++)
        {   
            int max = num[i];
            for(int j = i; j< i+size;j++)
            {              
                if(num[j]>max)
                    max = num[j];
            }
            result.push_back(max);
        }      
        return result;
    }
};

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值