实现时间复杂度为O(1)的Push,Pop,Min

定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。

首先:要决定使用链表结构实现还是顺序结构实现,对于顺序结构实现,当数据满的情况下进行Push时,需要开辟新的数组,进行复制,因此不能保证Push的时间复杂度为O(1);链表结构能够保证Push和Pop的时间复杂度为O(1)。

思路:我们需要一个辅助栈。每次push一个新元素的时候,同时将最小元素(或最小元素的位置。考虑到栈元素的类型可能是复杂的数据结构,用最小元素的位置将能减少空间消耗)push到辅助栈中;每次pop一个元素出栈的时候,同时pop辅助栈。

#pragma once
#include<iostream>
#include<assert.h>
#include<string>
using namespace std;
template<class T>
class Stack
{
public:
                Stack()
                                :_array( NULL)
                                , _size(0)
                                , _capacity(0)
                {}
                Stack(const Stack< T>& s )
                                :_array( new T [s._capacity])
                                , _size( s._size)
                                , _capacity( s._capacity)
                {
                                 for (int i = 0; i < s._size; ++i)
                                {
                                                _array[i] = s._array[i];
                                }
                }
                 Stack& operator=(Stack s)
                {
                                swap(_array, s._array);
                                swap(_size, s._size);
                                swap(_capacity, s._capacity);
                                 return *this ;
                }
                ~Stack()
                {
                                 //cout << "~Stack()" << endl;
                                 delete[] _array;
                                _size = _capacity = 0;
                }
                 void Push(const T& x)
                {
                                _CheckCapacity();
                                _array[_size++] = x;
                }
                 void Pop()
                {
                                 assert(!IsEmpty());
                                --_size;
                }
                 bool IsEmpty()
                {
                                 return _size == 0;
                }
                 bool IsFull()
                {
                                 return _size == _capacity;
                }
                 size_t Size()
                {
                                 return _size;
                }
                 const T &  Top()
                {
                                 return _array[_size - 1];
                }
protected:
                 void  _CheckCapacity()
                {
                                 if (_size == _capacity)
                                {
                                                _capacity = 2 * _capacity + 3;
                                                 T* tmp= new T[_capacity];
                                                 if (_array)
                                                {
                                                                 for (int i = 0; i < _size; ++i)
                                                                {
                                                                                tmp[i] = _array[i];
                                                                }
                                                                 delete[] _array;
                                                }
                                                _array = tmp;
                                }
                }
public:
                 T *_array;
                 size_t _size;
                 size_t _capacity;
};
//存储元素,保证Min.Top()是最小元素
template<class T>
class M
{
public:
                 void  PUSH(const T& x)
                {
                                _Simple.Push( x);
                                 if (_Min.Size() == 0)
                                {
                                                _Min.Push( x);
                                }
                                 else
                                {
                                                 if (x <= _Min.Top())
                                                                _Min.Push( x);
                                }
                }
                 void POP()
                {
                                 assert((!_Simple.IsEmpty()) && (!_Min.IsEmpty()));
                                 if(_Min.Top()==_Simple.Top())
                                                _Min.Pop();
                                _Simple.Pop();
                }
                 const T & Min()
                {
                                 return _Min.Top();
                }
protected:
                 Stack<T > _Min;//存到目前为止最小元素
                 Stack<T > _Simple;
};
//Min存储Simple中最小元素下标
template<class T>
class S_M
{
public:
                S_M()
                {}
                ~S_M()
                {}
                 void  PUSH(const T& x)
                {
                                _Simple.Push( x);
                                 if (_Min.Size() == 0)
                                {
                                                _Min.Push(_Simple.Size() - 1);
                                }
                                 else
                                {
                                                 if (x > _Simple._array[_Min.Size() - 1])
                                                {
                                                                _Min.Push(_Min.Top());
                                                }
                                                 else
                                                {
                                                                _Min.Push(_Simple.Size() - 1);
                                                }
                                }
                }
                 void POP()
                {
                                 assert((!_Simple.IsEmpty()) && (!_Min.IsEmpty()));
                                _Simple.Pop();
                                _Min.Pop();
                }
                 T& Min()
                {
                                 return _Simple._array[_Min.Top()];
                }
protected:
                 Stack<T > _Min;//存到目前为止最小元素下标
                 Stack<T > _Simple;
};
//测试用例
void Test1()
{
 S_M<int> s1;
 s1.PUSH(1);
 cout<<s1.Min() << endl;
}
void Test2()
{
 S_M<int> s1;
 s1.PUSH(1);
 s1.PUSH(2);
 cout << s1.Min() << endl;
}
void Test3()
{
 S_M<int> s1;
 s1.PUSH(5);
 s1.PUSH(4);
 s1.PUSH(3);
 s1.PUSH(2);
 s1.PUSH(2);
 cout << s1.Min() << endl;
}
void Test4()
{
 S_M<int> s1;
 s1.PUSH(3);
 s1.PUSH(6);
 s1.PUSH(2);
 s1.PUSH(1);
 s1.PUSH(0);
 cout << s1.Min() << endl;//0
 s1.POP();
 cout << s1.Min() << endl;//1
 s1.POP();
 cout << s1.Min() << endl;//2
 s1.POP();
 cout << s1.Min() << endl;//3
 s1.POP();
 cout << s1.Min() << endl;//3
}
void Test5()
{
 M<int> s1;
 s1.PUSH(3);
 s1.PUSH(6);
 s1.PUSH(2);
 s1.PUSH(1);
 s1.PUSH(0);
 cout << s1.Min() << endl;//0
 s1.POP();
 cout << s1.Min() << endl;//1
 s1.POP();
 cout << s1.Min() << endl;//2
 s1.POP();
 cout << s1.Min() << endl;//3
 s1.POP();
 cout << s1.Min() << endl;//3
}
时间: 2024-10-25 18:39:13

实现时间复杂度为O(1)的Push,Pop,Min的相关文章

解决 iOS View Controller Push/Pop 时的黑影

那么如何解决这个问题呢? 实际上很简单,如果这个 ViewController 是在 TabBarViewController 的 NavigationController 上 Push/Pop 的,那么只需要把 TabBarViewController 的 View 设置一下白色背景就可以了. 亲测设置NavigationController上的View的背景颜色为白色也可以解决.

javascript Array.push pop unshit shit

HTML代码: 1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Document</title> 7 <style type="text/css"> 8 *{font-family:Consolas;font-style: italic} 9 .sh

汇编 push ,pop指令

知识点: ? PUSH ? POP ? CALL堆栈平衡 ? RETN指令 一.PUSH入栈指令 (压栈指令): 格式: PUSH 操作数 //sub esp,4 ;mov [esp],EBP 操作数可以是寄存器,存储器,或者立即数 二.POP出栈指令 (弹栈指令) 格式:POP 操作数 //mov EBP,[esp] ;add esp,4 操作数是寄存器,或者存储器,不能是立即数 三.代码分析 1.测试PUSH和POP 与ESP栈顶指针的关系 2.CALL与ESP的关系 3.总结栈的特点(后进

js 的数组怎么push一个对象. Js数组的操作push,pop,shift,unshift JavaScript使用push方法添加一个元素到数组末 JavaScript数组函数unshift、shift、pop、push使用

push()函数用于向当前数组的添加一个或多个元素,并返回新的数组长度.新的元素将会依次添加到数组的末尾. 该函数属于Array对象,所有主流浏览器均支持该函数. 语法 array.push( item1 [,items... ] )参数 参数 描述item1 任意类型添加到当前数组末尾处的元素.items 可选参数/任意类型要添加到当前数组末尾处的其他项,可以有多个.注意:如果添加的元素类型为数组类型(Array),仍然会被当作一个元素看待,只是这个元素是数组类型而已.如果要合并两个数组,请使

ios7 push pop 动画突然消失的解决方案

不想看扯淡的同学,直接拉倒底部查看.......... 这几天开发的程序遇到了这样的问题. 突然之前在ios7运行的程序全无动画效果. 系统自带的push pop之类的也完全没有动画效果,就好像view直接add上去的一样. 蛋疼.... 查看了下代码.. 完全不知道该如何下手了. 怎么办.. 百度 谷歌... 关键字:ios7 动画效果消失 出现如下界面... 这他妈是什么啊... 换谷歌.. 谷歌还是比百度靠谱,但是点进去发现.这也只是跟我一样出现了这些现象提出来的问题,但是解决方案呢,wh

#pragma pack([n|push|pop]) 用法

#pragma pack(): 取消用户自定义的结构体成员(或类的数据成员)的对齐方式,恢复编译器默认的对齐方式(VC++和GCC编译器默认8个字节对齐,并且,我们可以在编译器的设置里更改编译器的默认设置). #pragma pack(n): n可以取以下这5个数中的任意一个:1.2.4.8.16 自定义结构体成员的对齐方式. #pragma pack(push): 英文单词push是“压”的意思.编译器编译到此处时将保存对齐状态. #pragma pack(pop): 英文单词pop是”取“的

UINavigationController 多次连续 Push Pop 问题

最近要实现一个 连续 pop 两次 又 Push 一个新的 MVC 的需求,所以把经历写出来分享一下. NavgationController 是 iOS 中最常用的控制器了,先看官网文档: The UINavigationController class implements a specialized view controller that manages the navigation of hierarchical content. This navigation interface m

js 的数组怎么push一个对象. Js数组的操作push,pop,shift,unshift JavaScrip

push()函数用于向当前数组的添加一个或多个元素,并返回新的数组长度.新的元素将会依次添加到数组的末尾. 该函数属于Array对象,所有主流浏览器均支持该函数. 语法 array.push( item1 [,items... ] )参数 参数 描述item1 任意类型添加到当前数组末尾处的元素.items 可选参数/任意类型要添加到当前数组末尾处的其他项,可以有多个.注意:如果添加的元素类型为数组类型(Array),仍然会被当作一个元素看待,只是这个元素是数组类型而已.如果要合并两个数组,请使

JavaScript中push ,pop ,concat ,join方法

push 方法 将新元素添加到一个数组中,并返回数组的新长度值. arrayObj.push([item1 [item2[. . . [itemN ]]]]) 说明 push 方法将以新元素出现的顺序添加这些元素(即追加新元素到末尾).如果参数之一为数组,那么该数组将作为单个元素添加到数组中.如果要合并两个或多个数组中的元素,需要使用 concat 方法. 版本要求在:5.5 应用于:array对象 pop 方法 移除数组中的最后一个元素并返回该元素. arrayObj.pop( ) 说明 如果