力扣HOT100刷题记录-STL Stack 常见写法与深度解析

7 阅读2分钟

STL Stack 常见写法与深度解析

概述

stack是 C++ STL 中的容器适配器(Container Adaptor),通常基于 dequevector实现。它只提供了 FILO(先进后出) ​ 的访问方式,是算法刷题和日常开发中的常用数据结构。

核心 API

方法功能描述时间复杂度
push()入栈元素O(1)
pop()弹出栈顶(无返回值)O(1)
top()访问栈顶元素(返回引用)O(1)
empty()检查是否为空O(1)
size()获取元素个数O(1)

1. 基础语法与定义

基本定义

#include <stack>
#include <vector>
#include <string>
using namespace std;

// 定义一个存放 int 类型元素的栈(默认基于 deque)
stack<int> s;

// 定义一个存放 string 类型元素的栈
stack<string> s2;

// 使用 vector 作为底层容器
stack<int, vector<int>> myVecStack;

注意事项

  • stack 本身不支持遍历或随机访问,仅能访问栈顶元素 top()
  • pop() 没有返回值,仅删除栈顶元素
  • 必须先检查 empty() 再调用 top() ,否则会导致未定义行为

2. 常见写法与处理手段

基础操作:压栈与弹栈

stack<int> mystack;

// 压栈操作
mystack.push(1);
mystack.push(2);
mystack.push(3); // 栈顶现在是 3

// 弹出操作
mystack.pop();  // 弹出 3

// 访问栈顶
if(!mystack.empty()){
    cout << mystack.top(); // 输出 2
}

安全获取并弹出元素

//  错误写法:pop() 没有返回值
// int val = mystack.pop(); 

//  正确写法:先获取再弹出
if(!mystack.empty()){
    int val = mystack.top();
    mystack.pop();
    // 使用 val...
}

遍历栈(需要临时栈)

// 如果需要遍历栈,需要创建临时栈
stack<int> temp = mystack;

while(!temp.empty()){
    cout << temp.top() << " ";
    temp.pop();
}

5. 进阶技巧与注意事项

技巧1:使用 pair 存储额外信息

// 在单调栈中存储值和索引
stack<pair<int, int>> st; // first: 值, second: 索引

// 在计算器问题中存储操作数和运算符
stack<int> nums;
stack<char> ops;

技巧2:空栈检查的重要性

//  危险写法
// cout << mystack.top(); // 如果栈空,UB

//  安全写法
if(!mystack.empty()){
    cout << mystack.top();
}

技巧3:栈的清空

// 方法1:循环弹出
while(!mystack.empty()){
    mystack.pop();
}

// 方法2:交换空栈(C++11+)
stack<int> empty;
swap(mystack, empty);

6. 常见错误与调试

错误1:忘记检查空栈

stack<int> s;
// s.pop(); //  未定义行为
// s.top(); //  未定义行为

if(!s.empty()){
    s.pop(); //  安全
}

错误2:误解 pop() 行为

stack<int> s;
s.push(1);
s.push(2);

//  错误:以为 pop() 返回元素
// int val = s.pop(); 

//  正确
int val = s.top();
s.pop();

错误3:遍历时修改栈

//  错误:遍历时修改栈大小
for(int i=0; i<s.size(); i++){
    s.pop(); // 大小在变化,循环次数错误
}

//  正确
while(!s.empty()){
    s.pop();
}