[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");

	}

}




 

 

你可能感兴趣的:(LeetCode)