20.包含min函数的栈

包含min函数的栈

题目链接

题目描述

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

注意:保证测试中不会当栈为空的时候,对栈调用pop()或者min()或者top()方法。

辅助栈

从之前两个栈实现队列,到实现带有min栈的功能。我发现了一个特点,想在栈的基础上增加或者改变功能,我们可以从增加一个辅助栈入手。

题目要求时间复杂度O(1)min算法,并不能暴力的保留栈每次push或pop操作之后的min值。

我们设立一个主栈s1,辅助栈s2。我们定义辅助栈保留我们所需要的最小值序列,保证辅助栈的top值总是栈push或者pop操作情况下的min值。

push

首先将value放入主栈

  • 如果此时辅助栈为空,那么将value放入辅助栈。min值的初始值
  • 辅助栈非空的情况下,若value < 辅助栈的top,那么将value放入辅助栈,更新min的值

这样在一系列push操作后,主栈包含所有push元素,辅助栈会存有从过程中的最小值序列。

例如push(4,3,5,2,7,1) 主栈(4,3,5,2,7,1) 辅助栈(4,3,2,1)

pop

我们保证了辅助栈的top值是任意过程的min值。在pop之前

  • 如果主栈和辅助栈的top值一样,那么也就是栈的min值要移除,那么主栈和辅助栈的top值都必须移除才能满足,此时辅助栈更新了min值。
  • 否则pop的值并不是主栈的min值(并不是辅助栈的top值),可以直接在主栈移除该值

例如 主栈(4,3,5,2,7,1) 辅助栈(4,3,2,1)

  1. pop第一次,主栈(4,3,5,2,7,1) 辅助栈(4,3,2)
  2. pop第二次,主栈(4,3,5,2) 辅助栈(4,3,2)

top

在push和pop操作我们为带有min栈实现了基础,top操作可直接返回主栈的top值

min

min操作直接返回当前情况的min值也就是辅助栈的top元素。从而实现了min算法时间复杂度O(1)。

class Solution {
    stack<int> s1, s2;
public:
    void push(int value) {
        s1.push(value);
        if (s2.empty())
        {
            s2.push(value);
        }
        else if (value < s2.top())
        {
            s2.push(value);
        }
    }
    void pop() {
        if (s1.top() == s2.top())
        {
            s1.pop();
            s2.pop();
        }
        else
        {
            s1.pop();
        }
    }
    int top() {
        return s1.top();
    }
    int min() {
        return s2.top();
    }
};

差值记录

以空栈到(4,3,5,2,7,1)的push过程为例。min为最小值,top为栈顶值,stack存储top与上一过程min的差值。

pushmintopstack
4440
333-1
5352
222-1
7275
111-1

我们记录min最小值,top栈顶值,栈存储差值便可以记录min值,从而可以节省一个栈的空间。

class Solution {
    stack<int> s;
    int t, ans;
    
public:
    void push(int value) {
        if (s.empty())
        {
            ans = value;
        }
      	// 存储入栈值与最小值的差值
        s.push(value - ans);
      	// 更新最小值
        ans = ans < value ? ans : value;
      	// 记录入栈值
        t = value;
    }
    void pop() {
      	// 差值小于0代表
        if (s.top() < 0)
        {
            ans -= s.top();
        }
        s.pop();
        t = t < 0 ? ans - t: ans;
    }
    int top() {
        return t;
    }
    int min() {
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值