[LeetCode]Sliding Window Maximum

题目链接:http://leetcode.com/2011/01/sliding-window-maximum.html

咳咳,很长时间没有写博客了。各种各样的事情,前段时间又被各种打击。调整了好久,终于状态好多了,SO,步入正轨了。

题目分析:其实就是给定一个长度为N的数组,以k为窗口长度,窗口自左向右滑动,求出每一次窗口的最大值。

如果用蛮力的话,复杂度是O(KN),因为每一次取出k个元素,都要重新算最大值。其实仔细观察可以发现,每一次窗口的滑动都是从左边出一个数,右边进一个数,这样的操作规则不就是队列的特质么,从一边进,另一边出。这样就把问题转化成求大小为k的队列的最大值,每一次队列出一个、进一个。

这样的话,前面已经有一篇相关的博客,给出了在O(1)的时间内得到队列的最小值。这里一样的,就不废话了。至于网站上的那种解法,自我感觉没我的好,所以就不说什么了。转载注明出处。谢谢~

参考代码,核心函数就是用栈模拟队列进和出的操作。

//将value压入到DataStack之中,并更新MaxStack
void Push(int *DataStack, int *MaxStack, int &TopIndex, int Value)
{
	assert(DataStack && MaxStack);
	MaxStack[TopIndex + 1] = max(TopIndex > -1 ? MaxStack[TopIndex] : INT_MIN, Value);
	DataStack[++TopIndex] = Value;
}
//元素出队列
void Pop()
{
	if(OutTop < 0)//the out stack is empty
	{
		while(InTop > 0)//将InStack里面的元素压到OutStack中,保留最后一个,直接pop
		{
			Push(Out, OutMax, OutTop, In[InTop--]);
		}
		--InTop;
	}
	else
	{
		--OutTop;
	}
}
//取得最大值
int GetMax()
{
	return max(InTop > -1 ? InMax[InTop] : INT_MIN, OutTop > -1 ? OutMax[OutTop] : INT_MIN);
}

照旧,给出辅助函数和main函数的调用过程

#include<stdio.h>
#include<limits.h>
#include<assert.h>
const int MAX_N = 30;
int In[MAX_N];
int Out[MAX_N];
int InMax[MAX_N];
int OutMax[MAX_N];
int InTop = -1;
int OutTop = -1;

inline int max(const int a, const int b)
{
	return a > b ? a : b;
}

void main()
{
	int n,k,i;
	int arr[MAX_N];
	while(scanf("%d %d", &n, &k) != EOF)
	{
		for(i = 0; i < n; ++i)
		{
			scanf("%d", &arr[i]);
		}
		InTop = OutTop = -1;
		for(i = 0; i < k; ++i)
		{
			Push(In, InMax, InTop, arr[i]);
		}
		printf("%d ", GetMax());
		for(; i < n; ++i)
		{
			Push(In, InMax, InTop, arr[i]);
			Pop();
			printf("%d ", GetMax());
		}
		printf("\n");
	}
}




 

 

posted @ 2013-09-03 19:47  pangbangb  阅读(347)  评论(0编辑  收藏  举报