栈的经典应用:字符串解码 & 每日温度 深度解析

目录

[一、字符串解码(LeetCode 394・中等)](#一、字符串解码(LeetCode 394・中等))

题目描述

解题思路

[Java 代码实现(标准栈版)](#Java 代码实现(标准栈版))

复杂度分析

核心知识点总结

[二、每日温度(LeetCode 739・中等)](#二、每日温度(LeetCode 739・中等))

题目描述

解题思路

[Java 代码实现(标准单调栈版)](#Java 代码实现(标准单调栈版))

复杂度分析


今天我们来拆解两道栈(Stack)的经典中等题:字符串解码每日温度。这两道题是栈在「嵌套结构处理」和「单调栈」场景下的标杆题目,吃透它们能帮你彻底掌握栈的灵活应用,是算法面试的高频考点。


一、字符串解码(LeetCode 394・中等)

题目描述

给定一个经过编码的字符串,返回它解码后的字符串。编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a2[4] 的输入。

示例:

plaintext

复制代码
输入:s = "3[a]2[bc]"
输出:"aaabcbc"

输入:s = "3[a2[c]]"
输出:"accaccacc"

输入:s = "2[abc]3[cd]ef"
输出:"abcabccdcdcdef"

解题思路

这道题的核心难点是嵌套结构 (比如 3[a2[c]]),栈是处理嵌套结构的天然工具,核心逻辑如下:

  1. 定义两个栈
    • countStack:存储重复次数 k
    • strStack:存储当前已经解码完成的字符串(用于嵌套场景的回溯)
  2. 遍历字符串,分 4 种情况处理
    • 遇到数字 :拼接多位数(比如 10[a] 中的 10
    • 遇到 [ :将当前数字压入 countStack,当前字符串压入 strStack,重置数字和当前字符串
    • 遇到 ] :弹出 countStack 的重复次数 k,弹出 strStack 的前缀字符串,将当前字符串重复 k 次后拼接到前缀后,更新当前字符串
    • 遇到字母:直接拼接到当前字符串
  3. 遍历结束后,当前字符串即为最终解码结果

Java 代码实现(标准栈版)

java

运行

复制代码
import java.util.Stack;

public class DecodeString {
    public String decodeString(String s) {
        Stack<Integer> countStack = new Stack<>();
        Stack<StringBuilder> strStack = new Stack<>();
        StringBuilder currentStr = new StringBuilder();
        int count = 0;

        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) {
                // 处理多位数,比如 10[a]
                count = count * 10 + (c - '0');
            } else if (c == '[') {
                // 遇到左括号,压入当前计数和当前字符串,重置
                countStack.push(count);
                strStack.push(currentStr);
                currentStr = new StringBuilder();
                count = 0;
            } else if (c == ']') {
                // 遇到右括号,弹出计数,拼接字符串
                int repeat = countStack.pop();
                StringBuilder prefix = strStack.pop();
                // 重复当前字符串 repeat 次,拼接到前缀后
                for (int i = 0; i < repeat; i++) {
                    prefix.append(currentStr);
                }
                currentStr = prefix;
            } else {
                // 普通字符,直接拼接
                currentStr.append(c);
            }
        }

        return currentStr.toString();
    }
}

复杂度分析

  • 时间复杂度:O(n),每个字符入栈 / 出栈最多一次,最终字符串长度为 O(n)
  • 空间复杂度:O(n),最坏情况(全嵌套)栈的深度为 O(n)

核心知识点总结

  1. 栈处理嵌套结构:利用栈的「后进先出」特性,完美匹配嵌套括号的「先入后出」逻辑
  2. 多位数处理 :通过 count = count * 10 + (c - '0') 处理连续数字
  3. 双栈设计:分别存储计数和字符串,实现嵌套场景的回溯与拼接

二、每日温度(LeetCode 739・中等)

题目描述

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例:

plaintext

复制代码
输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

输入: temperatures = [30,40,50,60]
输出: [1,1,1,0]

解题思路

这道题是单调栈的经典入门题,核心目标是「找下一个更大元素」,单调栈能将时间复杂度从 O(n2) 优化到 O(n):

  1. 维护一个单调递减栈 :栈中存储温度数组的下标,保证栈中下标对应的温度始终递减
  2. 遍历温度数组
    • 对于当前温度 temperatures[i],循环判断栈顶下标对应的温度是否小于当前温度
    • 若小于:弹出栈顶下标 top,计算天数差 i - top,存入结果数组 answer[top]
    • 若大于等于:将当前下标 i 压入栈中
  3. 遍历结束后,栈中剩余下标对应的结果为 0(默认初始化)

Java 代码实现(标准单调栈版)

java

运行

复制代码
import java.util.Stack;

public class DailyTemperatures {
    public int[] dailyTemperatures(int[] temperatures) {
        int n = temperatures.length;
        int[] answer = new int[n];
        // 栈中存储温度数组的下标,维护单调递减
        Stack<Integer> stack = new Stack<>();

        for (int i = 0; i < n; i++) {
            // 当前温度大于栈顶温度,弹出并计算天数差
            while (!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]) {
                int top = stack.pop();
                answer[top] = i - top;
            }
            // 将当前下标压入栈
            stack.push(i);
        }

        return answer;
    }
}

复杂度分析

  • 时间复杂度:O(n),每个下标入栈 / 出栈最多一次,总操作次数为 O(n)
  • 空间复杂度:O(n),最坏情况(严格递减)栈的大小为 O(n)
相关推荐
小O的算法实验室2 小时前
2025年EAAI,累积二项分布概率人工蜂群算法+机械工程设计全局优化,深度解析+性能实测
算法·论文复现·智能算法·智能算法改进
ID_180079054732 小时前
如何使用 Python 调用小红书笔记评论 API 时进行并发控制?
开发语言·笔记·python
树下水月2 小时前
使用python 一键生成,PGSQL的数据字典
python
高山流水&上善2 小时前
基于Qwen3-0.6B的光纤基础测试问答系统设计与实现
python·django
疯狂成瘾者2 小时前
PromptTemplate类解读
python·langchain
千谦阙听2 小时前
数据结构最终章:万字详解排序算法!(内部排序)
c语言·数据结构·学习·算法·排序算法
abant22 小时前
leetcode 76 最小覆盖子串
算法·leetcode·职场和发展
嵌入式的飞鱼2 小时前
SD NAND的坏块管理算法详解:如何保证数据完整
算法
kk在加油2 小时前
python学习笔记(基础语法与变量、容器)
笔记·python·学习