有关栈的经典算法题

栈算法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 树遍历

相关推荐
禅思院7 小时前
AI对话前端从入门到崩溃:一个长对话引发的五层优化战争【引子】
前端·面试·架构
带刺的坐椅7 小时前
用 ChatModel 构建 LLM 驱动的 Java 应用
java·ai·llm·solon·rag·chatmodel
赫媒派7 小时前
Gin 12年零破坏API,架构哲学如何练成?
后端·go·gin
fliter8 小时前
Arborium:把 tree-sitter 语法高亮打包成 Rust 文档生态的基础设施
后端
张三丰28 小时前
不会写代码的高管用Claude Code两天上线新程序,工程师接手后发现:一个Bug,让AI一天烧掉一个月服务器费!
后端
复杂网络8 小时前
AI 不睡觉,但它比你更会做实验
算法
Ai拆代码的曹操8 小时前
从一条转账 SQL 到分布式事务:5 种方案的全方位对比与实战
后端
林希_Rachel_傻希希8 小时前
web性能之相关路径——AI总结
前端·javascript·面试
掘金小豆8 小时前
Spring 事务失效的 6 大场景,你踩过几个?
后端·spring·面试
不好听6138 小时前
从零搭建一个 RAG 语义搜索系统 —— DEMO的初始阶段
javascript·面试·llm