左神算法学习日记——窗口

 一个可以找出窗口中最大/xiao值的数据结构

vector<int> maxval(vector<int> mat,int w)
{
	vector<int> res(mat.size()-w+1);
	deque<int> q;//用双端队列来表示窗口,队头元素永远是规定窗口中的最大值
	for (int i = 0; i < mat.size(); i++)
	{
        //保证双端队列中的元素从队头到队尾是从大到小排列的
		while (!q.empty() && mat[q.back()] <= mat[i])
			q.pop_back();
		q.push_back(i);
        //更新窗口,如果队头元素不在窗口内则弹出队头元素,
		if (q.front() <= i - w)
			q.pop_front();
		if (i - w + 1>=0)
			res[i - w + 1] = mat[q.front()]; //获得每个窗口中的最大值
	}
	return res;
}
//一个数组的子数组的最大值与最小值之差小于num,求得数组中这样的子数组的个数
int numsub(vector<int> vec, int num)
{
	deque<int> minq;//利用窗口结构找出子数组中最小值
	deque<int> maxq;//利用窗口结构找出子数组中最大值
	int res=0,L=0,R=0;
	while (L < vec.size())
	{
		while (R<vec.size())//找出以L为起点的子数组中符合条件的数组
		{
			while (!minq.empty() && vec[minq.back()]>=vec[R])
				minq.pop_back();
			minq.push_back(R);
			while (!maxq.empty() && vec[maxq.back()]<=vec[R])
				maxq.pop_back();
			maxq.push_back(R);
			if (vec[maxq.front()] - vec[minq.front()]>num)
				break;
			R++;//保证下一次不需要从头遍历子数组
		}
		if (minq.front() == L)//更新窗口
			minq.pop_front();
		if (maxq.front() == L)//更新窗口
			maxq.pop_front();
		res += (R - L);//加上当前子数组的数量
		L++;
	}
	return res;
}

猜你喜欢

转载自blog.csdn.net/w275412237/article/details/89647683