面试的时候,面试官让设计一个栈,要求有Push、Pop和获取最大最小值的操作,并且所有的操作都能够在O(1)的时间复杂度完成。

当时真没啥思路,后来在网上查了一下,恍然大悟,只能恨自己见识短浅、思路不够开阔,特地写个总结来学习一下。

其实思路挺简单,只是没有接触过的话,一时反应不过来。我们将栈中的每个元素都增加两个索引号,一个最大元素索引一个最小元素索引,这样我们可以根据栈只能访问栈顶元素的特性,在每个元素入栈时记下当前栈里面的最大最小元素的索引号,这样我们通过对栈顶元素的访问,就可以随时拿到当前栈中最大最小元素了,这是典型的空间换时间思想。

示例代码如下:

 #include<iostream>

 using namespace std;

 typedef int ElemType;

 class MinMaxStack
{
public:
MinMaxStack() : m_size() { }
~MinMaxStack() { } bool Push(const ElemType& e)
{
if (m_size >= STACK_MAXIMUM) {
return false;
} // 如果是第一个元素,则将最大最小元素索引都设置为0
if (m_size == ) {
m_stack[m_size].elem = e;
m_stack[m_size].maxIndex = ;
m_stack[m_size].minIndex = ;
}
else {
int minIndex = m_stack[m_size - ].minIndex;
int maxIndex = m_stack[m_size - ].maxIndex;
m_stack[m_size].elem = e; // 设置插入元素的最大元素索引:
// 若插入元素比当前最大元素大,则将其最大元素索引设置为它自己的索引
// 否则,设置为前一个元素的最大元素索引
if (e > m_stack[maxIndex].elem) {
m_stack[m_size].maxIndex = m_size;
}
else {
m_stack[m_size].maxIndex = maxIndex;
} // 设置插入元素的最小元素索引
// 若插入元素比当前最小元素小,则将其最小元素索引设置为它自己的索引
// 否则,设置为前一个元素的最小元素索引
if (e < m_stack[minIndex].elem) {
m_stack[m_size].minIndex = m_size;
}
else {
m_stack[m_size].minIndex = minIndex;
}
}
m_size++; return true;
} bool Pop(ElemType& e)
{
if (m_size == ) {
return false;
} m_size--;
e = m_stack[m_size].elem; return true;
} int Size()
{
return m_size;
} const ElemType& Min()
{
if (m_size == ) {
return INIT_VALUE;
} int minIndex = m_stack[m_size - ].minIndex;
return m_stack[minIndex].elem;
} const ElemType& Max()
{
if (m_size == ) {
return INIT_VALUE;
} int maxIndex = m_stack[m_size - ].maxIndex;
return m_stack[maxIndex].elem;
} private:
struct StackNode
{
StackNode(const ElemType& e = INIT_VALUE, int min = , int max = )
: elem(e), minIndex(min), maxIndex(max)
{
} ElemType elem;
int minIndex;
int maxIndex;
}; static const int STACK_MAXIMUM = ;
static const ElemType INIT_VALUE; StackNode m_stack[STACK_MAXIMUM];
int m_size;
}; const ElemType MinMaxStack::INIT_VALUE = -; // 测试代码
int main()
{
MinMaxStack stack;
stack.Push();
stack.Push();
stack.Push();
stack.Push();
stack.Push();
stack.Push();
stack.Push();
stack.Push(); cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "------------------------------------" << endl; ElemType e;
stack.Pop(e);
cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "pop = " << e << endl;
cout << "------------------------------------" << endl; stack.Pop(e);
cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "pop = " << e << endl;
cout << "------------------------------------" << endl; stack.Pop(e);
cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "pop = " << e << endl;
cout << "------------------------------------" << endl; stack.Pop(e);
cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "pop = " << e << endl;
cout << "------------------------------------" << endl; stack.Pop(e);
cout << "size = " << stack.Size() << endl;
cout << "min = " << stack.Min() << endl;
cout << "max = " << stack.Max() << endl;
cout << "pop = " << e << endl;
cout << "------------------------------------" << endl; return ;
}

设计一个Stack,要求Push、Pop、获取最大最小值时间复杂度都为O(1)的更多相关文章

  1. 数据结构---设计一个栈,push, pop, min 时间复杂度都是 O(1)

    普通的栈,push, pop 操作的复杂度是 O(1), 但是如果要找出其中的最小值,则需要 O(N)的时间. 题目要求 min 复杂度也是 O(1), 做法便是 空间换时间,每一步栈的最小值都用一个 ...

  2. 设计一个带有getmin功能的栈,保证时间复杂度在O(1)

    2017-06-22  20:56:10 需要得到最小值,最简单的思路就是遍历一遍求出最小值.但是这样的时间复杂度会是O(n),不满足O(1)的要求.于是想到在建立一个栈来保存最小值. 具体操作是建立 ...

  3. 算法与数据结构题目的 PHP 实现:栈和队列 设计一个有 getMin 功能的栈

    刚入手了一本<程序员代码面试指南>,书中题目的代码都是 Java 实现的,琢磨着把这些代码用 PHP 敲一遍,加深印象. 题目:设计一个有 getMin 功能的栈 —— 实现一个特殊的栈, ...

  4. 设计一个有getMin功能的栈

    [说明]: 本文是左程云老师所著的<程序员面试代码指南>第一章中“设计一个有getMin功能的栈”这一题目的C++复现. 本文只包含问题描述.C++代码的实现以及简单的思路,不包含解析说明 ...

  5. 设计一个有getMin功能的栈(2)

    题目: 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. 要求: 1.pop.push.getMin操作的时间复杂度都是O(1) 2.设计的栈类型可以输用现成的栈结构 解答 ...

  6. 设计一个有getMin功能的栈(1)

    题目: 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. 要求: 1.pop.push.getMin操作的时间复杂度都是O(1) 2.设计的栈类型可以输用现成的栈结构 解答 ...

  7. 常见面试算法题JS实现-设计一个有getMin功能的栈

    前言: 已经确定工作了-下周一正式入职,按理说应该是可以好好浪荡一周的,但是内心总是不安,总觉得自己这个水平真的太菜了,还是趁着现在有自己的时间,赶紧多看看书,多学习学习吧orz所以把之前校招买的书, ...

  8. 栈和队列问题:设计一个有 getMin 功能的栈

    [知识点] 栈是一个先进后出(FILO-First In Last Out)的数据结构,队列是一种先进先出(FIFO-First In First Out)的数据结构. [题目] 实现一个特殊的栈,在 ...

  9. 左神算法书籍《程序员代码面试指南》——1_01设计一个有getMin功能的栈

    [题目] 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. [要求] 1.pop.push.getMin操作的时间复杂度都是O(1).2.设计的栈类型可以使用现成的栈结构. ...

随机推荐

  1. ABAP 生产订单的创建与修改函数

    ABAP 生产订单的创建与修改函数转自http://www.cnblogs.com/aBaoRong/archive/2012/04/11/2441946.html   如果生产订单过多,可以批量创建 ...

  2. code标签和pre标签

    code标签: 1.code标签的定义: <code>标签, 用于表示计算机源代码或者其他机器可以阅读的文本内容.软件代码的编写者习惯了编写代码时的代码格式,那么这个<code> ...

  3. h5调用摄像头

    <!DOCTYPE html><html lang="zh-CN"><head> <meta charset="UTF-8&qu ...

  4. C# 二维数组相关知识记录

    //初始化一个数组 , ] { { , }, { , }, { , }, { , }, { , } }; //查某个字段的长度 print(name.GetLength()); //获得第一个字段的长 ...

  5. About Flash

    Take SAMSUNG K9F1G08U0E for example, and use S3C2416, Windows CE5.0 platform. 要让Flash工作起来,包括两部分: Fla ...

  6. UIView详解

    MVC架构模式   MVC(Model-View-Controller)是实现数据和显示数据的视图分离的架构模式(有一定规模的应用都应该实现数据和显示的分离).其中,M代表模型,就是程序中使用的数据和 ...

  7. T24基础-基本命令(1)

    如果你不知道什么是T24,那这篇文章对你意义不大.如果你所在银行IT刚好就准备使用或已经使用T24作为银行核心系统,那我的文章对你会很有帮助. 1. LIST  这个语句相当于SQL里的“select ...

  8. 查询expression的小工具

    今天在研究flipsolve的时候无意间写了个shelf tool,用于查询一大推节点中某些parameter的expression中是否存在我需要的关键字.就是简单的对所框选的节点进行一个循序查询参 ...

  9. js生成二维码(jquery自带)

    //引入js<script type="text/javascript" src="js/jquery.js"></script> &l ...

  10. 深入浅出SQL Server中的死锁

    简介 死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的.理解死锁首先需要对死锁所涉及的相关观念有一个理解. 一些基础知识 要理解SQL Server中的死锁,更好的方式是通过类比从更大的面理 ...