有关栈的经典算法题

栈算法10道经典例题(Java实现)

覆盖基础栈、单调栈、辅助栈、括号匹配、表达式求值、栈模拟队列、区间最值等面试高频题型,每题包含题意、思路、完整代码。

栈核心特性:后进先出LIFO,常用场景:括号校验、递归转迭代、单调性维护、临时缓存。

例题1:有效的括号(基础栈入门)

题目

给定只含()\[\]{}的字符串,判断括号是否有效闭合。

规则:左括号必须同类型右括号闭合;括号必须正确嵌套。

思路

遇左括号入栈;遇右括号,栈顶匹配则出栈,不匹配直接false;最后栈空才合法。

import java.util.Stack;

public boolean isValid(String s) {

Stack stack = new Stack<>();

for(char c : s.toCharArray()){

if(c == '(') stack.push(')');

else if(c == '') stack.push('');

else if(c == '{') stack.push('}');

else {

if(stack.isEmpty() || stack.pop() != c) return false;

}

}

return stack.isEmpty();

}

例题2:用栈实现队列(双栈模拟)

题目

仅使用两个栈实现队列的push、pop、peek、empty操作。

思路

in栈接收入队元素;out栈负责出队,out为空时一次性把in全部倒入out。

import java.util.Stack;

class MyQueue {

Stack in = new Stack<>();

Stack out = new Stack<>();

复制代码
public void push(int x) {
    in.push(x);
}

public int pop() {
    in2out();
    return out.pop();
}

public int peek() {
    in2out();
    return out.peek();
}

public boolean empty() {
    return in.isEmpty() && out.isEmpty();
}

private void in2out() {
    if(out.isEmpty()){
        while(!in.isEmpty()) out.push(in.pop());
    }
}

}

例题3:最小栈(辅助栈存最小值)

题目

设计栈,支持push、pop、top,额外O(1)获取栈中最小元素。

思路

主栈存元素;辅助栈同步压入当前最小值,出栈时同步弹出。

import java.util.Stack;

class MinStack {

Stack stack = new Stack<>();

Stack minStack = new Stack<>();

复制代码
public void push(int val) {
    stack.push(val);
    if(minStack.isEmpty()) minStack.push(val);
    else minStack.push(Math.min(val, minStack.peek()));
}

public void pop() {
    stack.pop();
    minStack.pop();
}

public int top() {
    return stack.peek();
}

public int getMin() {
    return minStack.peek();
}

}

例题4:逆波兰表达式求值(后缀表达式栈计算)

题目

后缀表达式数组,数字直接入栈;运算符弹出两个数计算,结果再入栈。

import java.util.Stack;

public int evalRPN(String\[\] tokens) {

Stack st = new Stack<>();

for(String s : tokens){

if("+".equals(s) || "-".equals(s) || "".equals(s) || "/".equals(s)){
int b = st.pop();
int a = st.pop();
int res;
switch(s){
case "+": res = a+b; break;
case "-": res = a-b; break;
case "
": res = a*b; break;

default: res = a/b;

}

st.push(res);

}else{

st.push(Integer.parseInt(s));

}

}

return st.peek();

}

例题5:字符串解码(嵌套字符串栈缓存)

题目

kencoded_string,把括号内字符串重复k次,支持嵌套,例如3a2\[bc]→abcbcabcbcabcbc。

思路

两个栈:数字栈存倍数,字符串栈存之前拼接好的前缀。

import java.util.Stack;

public String decodeString(String s) {

Stack numSt = new Stack<>();

Stack strSt = new Stack<>();

int num = 0;

StringBuilder curStr = new StringBuilder();

for(char c : s.toCharArray()){

if(Character.isDigit©){

num = num*10 + c-'0';

}else if(c == '['){

numSt.push(num);

strSt.push(curStr.toString());

num = 0;

curStr = new StringBuilder();

}else if(c == ']'){

int cnt = numSt.pop();

StringBuilder tmp = new StringBuilder(strSt.pop());

for(int i=0;i<cnt;i++) tmp.append(curStr);

curStr = tmp;

}else{

curStr.append©;

}

}

return curStr.toString();

}

例题6:柱状图中最大的矩形(单调递增栈经典Hard)

题目

给定高度数组,求柱状图能勾勒出的最大矩形面积。

思路

单调栈存下标,保证对应高度递增;遇到更小高度就弹出计算矩形宽度。

import java.util.Stack;

public int largestRectangleArea(int\[\] heights) {

Stack st = new Stack<>();

int maxArea = 0;

int\[\] arr = new intheights.length+2;

System.arraycopy(heights,0,arr,1,heights.length);

for(int i=0;i<arr.length;i++){

while(!st.isEmpty() && arri < arrst.peek()){

int h = arrst.pop();

int w = i - st.peek() - 1;

maxArea = Math.max(maxArea, h*w);

}

st.push(i);

}

return maxArea;

}

例题7:每日温度(单调递减栈)

题目

温度数组,返回每个位置要等多少天才会出现更高温度,没有填0。

思路

栈存下标,保持栈内温度递减;当前温度大于栈顶,弹出并计算天数差。

import java.util.Stack;

public int\[\] dailyTemperatures(int\[\] temperatures) {

int n = temperatures.length;

int\[\] res = new intn;

Stack st = new Stack<>();

for(int i=0;i<n;i++){

while(!st.isEmpty() && temperaturesi>temperaturesst.peek()){

int idx = st.pop();

residx = i - idx;

}

st.push(i);

}

return res;

}

例题8:删除字符串相邻重复项(栈快速消消乐)

题目

相邻两个相同字符直接删除,反复操作至无可删除,返回最终字符串。

思路

栈顶和当前字符相等则出栈,否则入栈,最后拼接栈内字符。

import java.util.Stack;

public String removeDuplicates(String s) {

Stack st = new Stack<>();

for(char c : s.toCharArray()){

if(!st.isEmpty() && st.peek() == c){

st.pop();

}else{

st.push©;

}

}

StringBuilder sb = new StringBuilder();

while(!st.isEmpty()) sb.append(st.pop());

return sb.reverse().toString();

}

例题9:小行星碰撞(栈模拟碰撞)

题目

整数数组,正数向右、负数向左;大小小的爆炸,相等同时爆炸,同向互不影响。

思路

遍历每个行星,和栈顶向左/向右判断碰撞,循环碰撞直至无冲突。

import java.util.Stack;

public int\[\] asteroidCollision(int\[\] asteroids) {

Stack st = new Stack<>();

for(int ast : asteroids){

boolean alive = true;

while(alive && ast < 0 && !st.isEmpty() && st.peek()>0){

int top = st.peek();

if(top < -ast){

st.pop();

}else if(top == -ast){

st.pop();

alive = false;

}else{

alive = false;

}

}

if(alive) st.push(ast);

}

int\[\] ans = new intst.size();

for(int i=ans.length-1;i>=0;i--) ansi = st.pop();

return ans;

}

例题10:二叉树迭代前序遍历(栈替代递归)

题目

不用递归,用栈实现二叉树前序遍历:根→左→右。

import java.util.ArrayList;

import java.util.List;

import java.util.Stack;

class TreeNode{

int val;

TreeNode left,right;

TreeNode(int x){val=x;}

}

public List preorderTraversal(TreeNode root) {

List res = new ArrayList<>();

if(root == null) return res;

Stack st = new Stack<>();

st.push(root);

while(!st.isEmpty()){

TreeNode cur = st.pop();

res.add(cur.val);

if(cur.right != null) st.push(cur.right);

if(cur.left != null) st.push(cur.left);

}

return res;

}

10道栈题型分类汇总

  1. 基础括号校验:例题1

  2. 双栈互相模拟:例题2(栈模拟队列)、例题3(最小辅助栈)

  3. 表达式计算:例题4 逆波兰求值

  4. 嵌套字符串处理:例题5 字符串解码

  5. 单调栈(面试高频):例题6 最大矩形、例题7 每日温度

  6. 相邻字符消除:例题8

  7. 模拟碰撞逻辑:例题9 小行星碰撞

  8. 递归转栈迭代:例题10 树遍历

相关推荐
手握风云-2 小时前
ProtoBuf:从序列化原理到高性能架构底座(一)
java·网络·架构
h_a_o777oah2 小时前
【算法专项】扩展域并查集:原理详解及解决大部分种类并查集问题(洛谷P5937 P2024 C++代码)
数据结构·c++·算法·acm·并查集·扩展域·逻辑建模
俊男无期2 小时前
【无标题】
笔记·其他
摇滚侠2 小时前
SpringMVC 入门到实战 配置类替换 XML 配置文件 86-91
xml·java·后端·spring·maven·intellij-idea
栗子~~2 小时前
金融场景下BigDecimal 运算规范 + 常用场景使用 + 数据库字段设计详解
java·数据库·金融
我登哥MVP2 小时前
SpringCloud Alibaba 核心组件解析:服务注册与发现(Nacos)
java·spring boot·后端·spring·spring cloud·java-ee·maven
兰令水2 小时前
leecodecode【单调栈】【2026.6.12打卡-java版本】
java·开发语言·算法
云烟成雨TD2 小时前
Agent Scope Java 2.x 系列【8】工具调用
java·人工智能·agent
TMT星球2 小时前
魔法原子上交会首秀VLA K02大模型,完成具身智能从“执行”到“理解”的能力跃迁
人工智能·算法·机器学习