从零开始写算法-栈-最小值(记忆化pair)

一、题目简介

题目描述

设计一个支持以下操作的栈:

  • push(x) ------ 将元素 x 推入栈中

  • pop() ------ 删除栈顶的元素

  • top() ------ 获取栈顶元素

  • getMin() ------ 检索栈中的最小元素

要求:

每个操作的时间复杂度必须是 O(1)。

二、思路分析

这道题的核心在于:

我们在每次 push 的时候,除了记录栈顶的值,还要顺便记录当前栈内的最小值。

换句话说,我们可以让每一层栈都携带两个信息:

复制代码

pair<当前元素, 当前最小值>

这样一来,每次入栈或出栈时,我们都可以在 O(1) 时间内拿到最小值。


⚙️ 三、关键设计

1. 栈的结构设计

我们用一个栈 stack<pair<int, int>> 来存放数据:

  • first 表示栈顶元素的值;

  • second 表示当前栈的最小值。

例如:

[(2, 2), (5, 2), (1, 1)]

此时:

  • 栈顶 first=1;

  • 栈顶 second=1;

  • 当前最小值为 1。


2. 初始状态设计

我们在构造函数中手动压入一个初始值:

st.push(pair(0, INT_MAX));

为什么要这么做?

  • 因为这样可以确保第一个入栈的元素一定比 INT_MAX 小;

  • 避免在第一次 push 时 st.top() 为空导致出错。


3.入栈逻辑

每当我们 push(val) 时:

  • 当前最小值应为:

    min(val, st.top().second)

    即「当前值」与「之前的最小值」中取较小的一个;

  • 再用 pair{val, 当前最小值} 压栈。


4️⃣ 出栈逻辑

直接 st.pop() 即可,当前最小值自动回退为下一个元素的 second。


5️⃣ top() 与 getMin()

因为 st.top() 返回的是一个 pair<int, int>:

  • st.top().first → 栈顶元素;

  • st.top().second → 当前最小值。

四、完整代码

cpp 复制代码
class MinStack {
    // 思路: 维护栈顶的最小元素 pair<栈顶元素, 最小值>
    stack<pair<int, int>> st;

public:
    MinStack() {
        // 初始时推入一个虚拟节点,避免空栈判断
        st.push(pair(0, INT_MAX));
    }
    
    void push(int val) {
        st.push(pair{val, min(val, st.top().second)});
    }
    
    void pop() {
        st.pop();
    }
    
    int top() {
        return st.top().first;
    }
    
    int getMin() {
        return st.top().second;
    }
};

五、运行逻辑示例

以 push(2), push(5), push(1) 为例:

操作 栈内容 (pair<值, 当前最小值>)
初始 (0, INF)
push(2) (0, INF), (2, 2)
push(5) (0, INF), (2, 2), (5, 2)
push(1) (0, INF), (2, 2), (5, 2), (1, 1)

此时:

  • top() → 1

  • getMin() → 1

  • pop() 后最小值回退为 2


六、知识要点总结

知识点 说明
pair<int,int> 同时存两个相关的变量
.first / .second 分别取出 pair 中的两个值
st.top() 返回栈顶元素(是 pair)
INT_MAX 初始化为无穷大,方便比较
min(a, b) 返回较小值

七、总结

使用 pair 维护最小值 的思路非常高效:

  • 不需要额外的数据结构;

  • 所有操作都是 O(1);

  • 逻辑简洁、实现优雅。

这类"带记忆功能"的栈思想非常常见,

比如 "含最大值的栈"、"含和的栈" 都能用相同的套路解决。

相关推荐
轩轶子1 小时前
Python CLI Todo:一次数据结构错误引发的 Bug
数据结构·python·bug
CQU_JIAKE2 小时前
9.28【A】
数据结构
code斗11 小时前
Java数据结构:堆详解
java·开发语言·数据结构
Elaine33613 小时前
数据结构与算法-程序
数据结构·python·算法·计算机基础·编程基础
Logic10114 小时前
C语言/数据结构位运算题解:异或XOR找出游戏速通中的“独特初始能量值“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
Bruce_Liuxiaowei16 小时前
Python 字典默认值完全指南:从 KeyError 到 defaultdict
开发语言·数据结构·python·字典
All for pursuit.20 小时前
【二叉树-10】114.二叉树展开为链表
数据结构·c++·算法·leetcode·链表
心中有你02141 天前
C语言埃氏筛法(素数筛选)
c语言·数据结构·算法
释厄6231 天前
多黑洞具现论·物理/生物/金融三域显化·虚拟宇宙黑洞·奇点=0 圆圈
开发语言·数据结构·人工智能·程序人生·安全威胁分析
库玛西1 天前
攻克 408 数据结构:图论基石深度拆解(数学极值推演 + 存储内存剖析 + BFS/DFS 双核模板)
数据结构·算法·深度优先·广度优先·图搜索算法