在O(1)时间复杂度中,求栈中的最小元素

4 篇文章 0 订阅


定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。

输入:

输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n(1<=n<=1000000), n代表将要输入的操作的步骤数。
接下来有n行,每行开始有一个字母Ci。
Ci=’s’时,接下有一个数字k,代表将k压入栈。
Ci=’o’时,弹出栈顶元素。

输出:

对应每个测试案例中的每个操作,
若栈不为空,输出相应的栈中最小元素。否则,输出NULL。


思路:

基本思路, 另外建立一个辅助栈,辅助栈栈顶记录的当天栈中最小元素的值,他与数据栈执行一样的操作,当数据栈入栈是,辅助栈也入栈,入栈的元素为min(数据栈栈顶元素,辅助栈栈顶元素),元数据出栈时,辅助栈也出栈。

进一步优化

辅助栈主要是记录数据栈当前的最小值,可以进一步优化空间。考虑如下情况,如果数据栈入栈的元素为 a,他比元数据栈最小元素栈小,在入栈前后栈的最小元素没有发生变化。既然没有发生变化,辅助栈也不要更新最小值,也不记录。

辅助栈出栈,是数据栈出栈的元素值小于辅助栈的栈顶元素


代码

#include<iostream>
#include<stack>
using namespace std;
/*
需要考虑的问题
1 如果栈中元素为空,执行pop操作时该怎么定义;
2. 入栈中有相同元素时该怎么办,加入技术min(min栈)
3, 元素集为空时,min返回NULL
*/
class MyStack
{
public :
	MyStack()
	{
		myStack=new stack<int>;
		min=new stack<int>;
		state=0;
	}
	void push(int a)
	{
		myStack->push(a);
		state=0;
		if(min->empty())
		{
			min->push(a);
		}
		else if(a<=min->top())
		{
			min->push(a);
			//printf("push into min\n");
			//printf(" %d size min \n",min->size());
		}

	}

	int pop()
	{
		int value;
		if(myStack->empty())
		{
			state=-1;
			return -1;
		}
		else
		{
			value=myStack->top();
			myStack->pop();
			if(myStack->empty())
			{ state=-1;}
			if(value==min->top())
			{
				min->pop();
				//printf(" %d pop int min \n",min->size());
			}
		}

		return value;
	}
	
	int minValue()
	{
		if(min->empty())
		{
			//printf("NULL\n")
		}
		else
		{
		return min->top();
		}
	}

	int getState()
	{
		int tem=state;
		state=0;
		return tem;
	}
private :
stack<int> *myStack;
stack<int >*min;
int state;
};

int main()
{
	MyStack mStack;
	int count;
	scanf("%d",&count);
	getchar();
	if(count<=0)
	{
		printf("NULL");
	}
	else
	{
		int i=0;
		char operation;
		
		int inNum;
		while(i<count)
		{
			scanf("%c",&operation);
			if('s'==operation)
			{
				i++;
				scanf("%d",&inNum);
				mStack.push(inNum);
				printf("%d\n",mStack.minValue());
			}
			else if('o'==operation)
			{
				i++;
				mStack.pop();
				if(-1==mStack.getState())
				{
					printf("NULL\n");
				}
				else 
				{
					printf("%d\n",mStack.minValue());
				}
			}
			else
			{
				//printf("error input %c",operation);
			}
		}
	}
	return 1;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值