hot100 栈专题

1 有效的括号

不难,但是要考虑多种情况

技巧:入栈的时候,( 就入 ), 就入

如果遇到右括号,则判断stack是否为空,考虑())的情况

再考虑当前字符c != stack.peek()的情况,也就是(( ] )的情况。

上面这两种情况直接返回fals就行。

第三种情况就是正常匹配,当前字符是)且栈顶是(,那么直接stack.pop()就行。

最后结束for循环,返回stack.isEmpty();

如果不为空,说明左括号有剩余, \[ \[ 的情况就是,直接返回false;栈空则说明是有效的括号,返回true;

java 复制代码
class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack = new LinkedList<>();
        int len = s.length();
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) == '(') {
                stack.push(')');
            } else if (s.charAt(i) == '[') {
                stack.push(']');
            } else if (s.charAt(i) == '{') {
                stack.push('}');
            } else if (stack.size() == 0 || s.charAt(i) != stack.peek()) {
                return false;
            } else {
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

2 最小栈

核心思路:辅助栈法(最优解)

主栈:存储所有入栈的元素,实现普通栈的基本操作;

辅助栈:同步存储「当前主栈中的最小值」,保证辅助栈的栈顶始终是主栈当前的最小值。

push:主栈入栈元素,辅助栈入栈「当前元素与辅助栈顶的较小值」;

pop:主栈和辅助栈同时出栈(保证两者长度一致);

getMin:直接返回辅助栈的栈顶元素。

java 复制代码
class MinStack {
    private Deque<Integer> mainStack;
    private Deque<Integer> minStack;
    public MinStack() {
        mainStack = new LinkedList<>();
        minStack = new LinkedList<>();
        minStack.push(Integer.MAX_VALUE);
    }
    
    public void push(int val) {
        mainStack.push(val);
        int curMin = Math.min(val, minStack.peek());
        minStack.push(curMin);
    }
    
    public void pop() {
        mainStack.pop();
        minStack.pop();
    }
    
    public int top() {
        return mainStack.peek();
    }
    
    public int getMin() {
        return minStack.peek();
    }
}

3 字符串解码

数字栈:存储待处理的重复次数 k(处理多位数,如 12abc 中的 12);

字符串栈:存储待拼接的前缀字符串(处理嵌套时的外层字符串,如 3a2\[b] 中 2b 外层的 a);

遍历逻辑:

遇到数字:累积计算多位数(如 12 = 1*10 + 2);

遇到 [:将当前累积的数字压入数字栈,当前拼接的字符串压入字符串栈,然后重置数字和字符串;

遇到 ]:弹出数字栈的重复次数 k,弹出字符串栈的前缀字符串,将当前字符串重复 k 次后拼接到前缀后;

遇到字母:直接拼接到当前字符串。

java 复制代码
import java.util.Deque;
import java.util.LinkedList;

class Solution {
    public String decodeString(String s) {
        // 数字栈:存储待执行的重复次数(处理嵌套结构时的"重复指令")
        Deque<Integer> numStack = new LinkedList<>();
        // 字符串栈:存储括号外层的前缀字符串(处理嵌套时的"外层存档")
        Deque<String> strStack = new LinkedList<>();
        // 当前正在拼接的临时字符串(括号内待重复的内容)
        StringBuilder curStr = new StringBuilder();
        // 当前累积的数字(处理多位数,如"12[a]"中的12需要逐步计算)
        int curNum = 0;
        // 将字符串转为字符数组,方便逐个遍历
        char[] sArr = s.toCharArray();
        
        // 遍历每个字符,逐字符处理解码逻辑
        for (char c : sArr) {
            // 情况1:当前字符是数字 → 累积计算多位数
            if (Character.isDigit(c)) {
                // 例如:curNum=1,遇到'2' → 1*10 + 2 = 12
                curNum = curNum * 10 + (c - '0');
            } 
            // 情况2:当前字符是左括号'[' → 存档当前状态,准备处理括号内内容
            else if (c == '[') {
                // 1. 把当前累积的重复次数压入数字栈(存档)
                numStack.push(curNum);
                // 2. 把当前拼接的字符串压入字符串栈(存档外层前缀)
                strStack.push(curStr.toString());
                // 3. 重置临时数字,准备处理括号内的新数字
                curNum = 0;
                // 4. 重置临时字符串,准备拼接括号内的内容
                curStr = new StringBuilder();
            } 
            // 情况3:当前字符是右括号']' → 拼接重复后的字符串
            else if (c == ']') {
                // 1. 弹出数字栈顶的重复次数(本次要重复的次数)
                int loop = numStack.pop();
                // 2. 弹出字符串栈顶的前缀(括号外的内容)
                String prefix = strStack.pop();
                // 3. 新建临时字符串,先拼接外层前缀
                StringBuilder temp = new StringBuilder(prefix);
                // 4. 把当前括号内的字符串重复指定次数,拼接到前缀后
                for (int i = 0; i < loop; i++) {
                    temp.append(curStr.toString());
                }
                // 5. 更新临时字符串为拼接后的结果,继续处理外层逻辑
                curStr = temp;
            } 
            // 情况4:当前字符是字母 → 直接拼接到临时字符串
            else {
                curStr.append(c);
            }
        }
        // 遍历结束,返回最终拼接完成的解码字符串
        return curStr.toString();
    }
}

4 每日温度

单调递减栈

先把下标0push入栈

然后从1开始,如果温度比栈顶下标的温度低,那就入栈。

如果下标i对应的温度比栈顶下标的温度高,那么就进入while循环,!st.isEmpty()&&ti >tst.peek()

然后给resst.peek()赋值为i-st.peek()

st.pop()

最后退出while循环,把i push进去

java 复制代码
class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        Deque<Integer> st = new LinkedList<>();
        st.push(0);
        int len = temperatures.length;
        int[] res = new int[len];
        for (int i = 1; i < len; i++) {
            if (temperatures[i] <= temperatures[st.peek()]) {
                st.push(i);
            } else {
                while (!st.isEmpty() && temperatures[i] > temperatures[st.peek()]) {
                    res[st.peek()] = i - st.peek();
                    st.pop();
                }
                st.push(i);
            }
        }
        return res;
    }
}

5 柱状图中最大的矩形

单调递增栈

遇到hi < hst.peek()的就while()出栈

height = hst.pop()

width = i - st.peek() - 1;

更新area

加左右哨兵,同意边界处理,让第一个能入栈,最后一个能弹出。

java 复制代码
class Solution {
    public int largestRectangleArea(int[] heights) {
        int len = heights.length;
        if (len == 1) return heights[0];
        int[] newHeights = new int[len + 2];
        for (int i = 0; i < len; i++) {
            newHeights[i + 1] = heights[i];
        }
        newHeights[0] = 0;
        Deque<Integer> st = new LinkedList<>();
        int res = 0;
        for (int i = 0; i < newHeights.length; i++) {
            while (!st.isEmpty() && newHeights[i] < newHeights[st.peek()]) {
                int curIndex = st.pop();
                int curHeight = newHeights[curIndex];
                int width = i - st.peek() - 1;
                res = Math.max(res, width * curHeight);
            }
            st.push(i);
        }
        return res;
    }
}
相关推荐
叫我:松哥7 小时前
基于卷积神经网络的人脸情绪识别算法,引入残差连接与SE注意力模块
人工智能·深度学习·神经网络·算法·cnn·迁移学习·图像识别
KaMeidebaby8 小时前
卡梅德生物技术快报|羊驼免疫:分子生物学实战:基于羊驼免疫的重链抗体制备与全流程验证方案
前端·网络·数据库·人工智能·算法·百度
oort1238 小时前
AI+基层治理·智慧政务解决方案——AI民意速办智能助手
大数据·人工智能·算法·政务
渡之8 小时前
GeoBridge 深度解析:语义锚定多视图基础模型,重塑无人机跨视角地理定位
深度学习·算法·动态规划·无人机
一口吃俩胖子8 小时前
【脉宽调制DCDC功率变换学习笔记024】电压反馈补偿和环路增益
笔记·学习·算法
洛水水8 小时前
【力扣100题】80.寻找旋转排序数组中的最小值
数据结构·算法·leetcode
ting94520008 小时前
VC Boom 技术架构与核心算法深度解
人工智能·算法·架构
无限码力8 小时前
美团研发岗 5月9号笔试真题 - 正整数矩阵
算法·美团笔试真题·美团研发岗笔试真题·美团0509笔试真题
Smilecoc8 小时前
决策树(二):决策树的划分选择
算法·决策树·机器学习
hetao17338379 小时前
2026-05-25~06-11 hetao1733837 的刷题记录
c++·算法