算法2_实现一个栈,除了push和pop操作,还要实现min函数以返回栈中的最小值,时间复杂度都为O(1)(keep it up)
2016-07-19 23:51
417 查看
实现一个栈,除了push和pop操作,还要实现min函数以返回栈中的最小值。
push,pop和min函数的时间复杂度都为O(1)。
看到这个题目最直接的反应是用一个变量来保存当前栈的最小值,让我们来看看这样可行否?
如果栈一直push那是没有问题,入栈元素如果比当前最小值还小,那就更新当前最小值。
可是如果pop掉的栈顶元素就是最小值,那么我们如何更新最小值呢?显然不太好办。
既然只用一个变量没法解决这个问题,那我们就增加变量。如果说每个结点除了保存当前的 值,
另外再保存一个从该结点到栈底的结点中的最小值。那么,不论哪个结点成为了栈顶结 点,
我们都有办法取得剩下的这些元素的最小值。代价是付出的空间多了一倍。代码不写了。
下面在介绍一种方法,我们可以在用一个栈来保存栈的最小值:
比如有一组数要入栈: 10 11 6 2 12
栈S1: 10 11 6 2 12
栈S2: 10 6 2
即到栈顶12时,最小值是2, 如果S1栈12出,和S2.top比较,如果大于S2.top,则S2不做
任何操作,如果等于S2.top, 则S2.pop(); 比如S1的2出栈时,2 == S2.top(), 然后S2.pop();
这样就节省了很多空间。
但是上述方法还有问题:
比如数据
S1:10 11 6 2 2 2 12 这时
S2:10 11 6 2
当S1中2出栈时,S2中的2也会出栈,这样我们才去S1的最小值时就是6,明显错了。解决方法就是
S2中每个元素添加一个计数器。这样当连续3次2出栈,S2中的2才出栈。
[html] view
plain copy
#include <iostream>
#include <stack>
struct DataCount
{
int data;
int count;
DataCount(int vData = std::numeric_limits<int>::infinity()) : data(vData), count(0) {}
};
class Stack
{
public:
Stack() {}
~Stack() {}
void push(int vData)
{
m_Data.push(vData);
if (m_MinData.empty())
{
m_MinData.push(DataCount(vData));
}
else
{
if (vData < m_MinData.top().data)
{
m_MinData.push(DataCount(vData));
}
else if (vData == m_MinData.top().data)
{
++m_MinData.top().count;
}
}
}
void pop()
{
if (m_Data.empty())
{
std::cout << "Empty stack\n";
return;
}
int Data = m_Data.top();
m_Data.pop();
if (Data == m_MinData.top().data)
{
if (--m_MinData.top().count == 0)
{
m_MinData.pop();
}
}
}
int getMin()
{
if (m_MinData.empty())
{
std::cout << "Empty stack\n";
return;
}
return m_MinData.top().data;
}
private:
std::stack<int> m_Data;
std::stack<DataCount> m_MinData;
};
原文来自:http://blog.csdn.net/xiaoliangsky/article/details/38762113?utm_source=tuicool&utm_medium=referral
push,pop和min函数的时间复杂度都为O(1)。
看到这个题目最直接的反应是用一个变量来保存当前栈的最小值,让我们来看看这样可行否?
如果栈一直push那是没有问题,入栈元素如果比当前最小值还小,那就更新当前最小值。
可是如果pop掉的栈顶元素就是最小值,那么我们如何更新最小值呢?显然不太好办。
既然只用一个变量没法解决这个问题,那我们就增加变量。如果说每个结点除了保存当前的 值,
另外再保存一个从该结点到栈底的结点中的最小值。那么,不论哪个结点成为了栈顶结 点,
我们都有办法取得剩下的这些元素的最小值。代价是付出的空间多了一倍。代码不写了。
下面在介绍一种方法,我们可以在用一个栈来保存栈的最小值:
比如有一组数要入栈: 10 11 6 2 12
栈S1: 10 11 6 2 12
栈S2: 10 6 2
即到栈顶12时,最小值是2, 如果S1栈12出,和S2.top比较,如果大于S2.top,则S2不做
任何操作,如果等于S2.top, 则S2.pop(); 比如S1的2出栈时,2 == S2.top(), 然后S2.pop();
这样就节省了很多空间。
但是上述方法还有问题:
比如数据
S1:10 11 6 2 2 2 12 这时
S2:10 11 6 2
当S1中2出栈时,S2中的2也会出栈,这样我们才去S1的最小值时就是6,明显错了。解决方法就是
S2中每个元素添加一个计数器。这样当连续3次2出栈,S2中的2才出栈。
[html] view
plain copy
#include <iostream>
#include <stack>
struct DataCount
{
int data;
int count;
DataCount(int vData = std::numeric_limits<int>::infinity()) : data(vData), count(0) {}
};
class Stack
{
public:
Stack() {}
~Stack() {}
void push(int vData)
{
m_Data.push(vData);
if (m_MinData.empty())
{
m_MinData.push(DataCount(vData));
}
else
{
if (vData < m_MinData.top().data)
{
m_MinData.push(DataCount(vData));
}
else if (vData == m_MinData.top().data)
{
++m_MinData.top().count;
}
}
}
void pop()
{
if (m_Data.empty())
{
std::cout << "Empty stack\n";
return;
}
int Data = m_Data.top();
m_Data.pop();
if (Data == m_MinData.top().data)
{
if (--m_MinData.top().count == 0)
{
m_MinData.pop();
}
}
}
int getMin()
{
if (m_MinData.empty())
{
std::cout << "Empty stack\n";
return;
}
return m_MinData.top().data;
}
private:
std::stack<int> m_Data;
std::stack<DataCount> m_MinData;
};
原文来自:http://blog.csdn.net/xiaoliangsky/article/details/38762113?utm_source=tuicool&utm_medium=referral
相关文章推荐
- opensns服务器功能完善
- PHP开发网站第二步:关联并配置PHP与Apache2.4
- Windows平台下编译OpenCV扩展的opencv_contrib
- 配置基于Devstack的嵌套KVM虚拟化
- Linux 多线程编程(不限Linux)
- JavaEE体系架构概述、MyBatis总结
- 云服务器 ECS Linux IO 占用高问题排查方法
- shell脚本练习(二)
- 架构师与网红
- [知识整理]Linux系统WIFI知识的一些整理
- CENTOS YUM软件源
- BeanUtils.copyProperties
- centos telnet命令
- crontab+shell 作业流程调度
- 自定义zabbix监控脚本
- 网站运营先考虑用户忠诚度,再去想产品知名度
- 网站运营先考虑用户忠诚度,再去想产品知名度
- win10+VS2013+OPENCV如何配置于仕琪人脸检测算法
- Linux Centos 通过LVM调整分区
- 架构中的设计原则