在前面的博客中,我们已经探讨了数组、栈、哈希表等多类经典题目的解法。今天,我们继续深入 LeetCode 热题 100,聚焦 155. 最小栈 、394. 字符串解码 、739. 每日温度 这三道题目,解析其解题思路、算法特性与代码实现细节。
一、155. 最小栈
📌 题目描述
设计一个支持 push、pop、top操作,并能在常数时间内检索到最小元素的栈。
要求:
-
MinStack()初始化栈对象。 -
void push(int val)将元素val推入栈。 -
void pop()删除栈顶元素。 -
int top()获取栈顶元素。 -
int getMin()获取栈中的最小元素。
🧠 解题思路:双栈法(主栈 + 辅助栈)
核心思想是:用辅助栈 Minst记录每一步操作后栈中的最小值。
-
主栈
st:存储所有元素。 -
辅助栈
Minst:存储"当前栈中最小值"的历史记录。每次push时,将当前最小值(与主栈顶比较)压入Minst;pop时,两个栈同步弹出。
这样,getMin()只需返回 Minst.top(),时间复杂度为 O(1)。
💻 代码实现(C++)
class MinStack {
private:
stack<int> st; // 主栈,存储所有元素
stack<int> Minst; // 辅助栈,存储当前最小值
public:
MinStack() {}
void push(int val) {
st.push(val);
// 若辅助栈为空,或新值 <= 当前最小值,则压入辅助栈
if (Minst.empty() || val <= Minst.top()) {
Minst.push(val);
}
}
void pop() {
if (st.top() == Minst.top()) { // 如果主栈顶是当前最小值,辅助栈也要弹出
Minst.pop();
}
st.pop();
}
int top() {
return st.top();
}
int getMin() {
return Minst.top();
}
};
✅ 时间复杂度:所有操作 O(1)
✅ 空间复杂度:O(n)(最坏情况辅助栈存所有元素)
二、394. 字符串解码
📌 题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则: k[encoded_string],表示方括号内部的 encoded_string正好重复 k次。k保证为正整数。
示例:
-
输入:
"3[a]2[bc]"→ 输出:"aaabcbc" -
输入:
"3[a2[c]]"→ 输出:"accaccacc"
🧠 解题思路:栈 + 递归思想(或迭代模拟)
使用栈来模拟嵌套结构:
-
遇到数字:累积数字
num。 -
遇到
[:将当前res和num压栈,重置res和num。 -
遇到
]:弹出栈顶的prev_res和count,将当前res重复count次后拼接到prev_res后面。 -
遇到字母:直接拼接到
res。
💻 代码实现(C++)
class Solution {
public:
string decodeString(string s) {
stack<pair<string, int>> st; // 存储 (当前字符串, 重复次数)
string res = "";
int num = 0;
for (char c : s) {
if (isdigit(c)) {
num = num * 10 + (c - '0'); // 累积数字
} else if (c == '[') {
st.push({res, num}); // 保存当前状态
res = ""; // 重置当前字符串
num = 0; // 重置重复次数
} else if (c == ']') {
auto [prev_res, count] = st.top(); st.pop();
string repeated = "";
for (int i = 0; i < count; i++) {
repeated += res;
}
res = prev_res + repeated; // 拼接回上一层
} else {
res += c; // 普通字符直接追加
}
}
return res;
}
};
✅ 时间复杂度:O(n)(每个字符处理一次)
✅ 空间复杂度:O(n)(栈深度最坏为嵌套层数)
三、739. 每日温度
📌 题目描述
给定一个整数数组 temperatures,表示每天的温度,返回一个数组 answer,其中 answer[i]是指对于第 i天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0来代替。
示例:
- 输入:
[73,74,75,71,69,72,76,73]→ 输出:[1,1,4,2,1,1,0,0]
🧠 解题思路:单调栈(递减栈)
单调栈 是解决"下一个更大元素"类问题的经典方法。
-
维护一个单调递减栈(栈中存储索引,对应温度递减)。
-
遍历温度数组:
-
若当前温度 > 栈顶索引对应的温度,则弹出栈顶,计算天数差(
i - prevIndex),并记录到answer[prevIndex]。 -
将当前索引入栈。
-
这样,每个元素最多入栈出栈一次,时间复杂度 O(n)。
💻 代码实现(C++)
class Solution {
public:
vector<int> dailyTemperatures(vector<int>& temperatures) {
int n = temperatures.size();
vector<int> answer(n, 0);
stack<int> st; // 存储索引,维持单调递减
for (int i = 0; i < n; i++) {
// 当前温度比栈顶温度高,说明找到了"下一个更高温度"
while (!st.empty() && temperatures[i] > temperatures[st.top()]) {
int prevIndex = st.top(); st.pop();
answer[prevIndex] = i - prevIndex;
}
st.push(i); // 当前索引入栈
}
return answer;
}
};
✅ 时间复杂度:O(n)
✅ 空间复杂度:O(n)(栈空间)
🎯 总结
| 题目 | 核心算法 | 时间复杂度 | 空间复杂度 | 关键点 |
|---|---|---|---|---|
| 155. 最小栈 | 双栈法 | O(1) | O(n) | 辅助栈记录历史最小值 |
| 394. 字符串解码 | 栈 + 状态保存 | O(n) | O(n) | 嵌套结构的模拟 |
| 739. 每日温度 | 单调栈(递减) | O(n) | O(n) | "下一个更大元素"问题 |
这三道题分别代表了栈的多种应用场景:
-
最小栈:栈的扩展功能(常数时间查最小值)。
-
字符串解码:栈处理嵌套结构。
-
每日温度:单调栈解决"下一个更大元素"。
掌握这些经典题型,不仅能提升算法思维,也能在面试中游刃有余。后续我们将继续探索更多 LeetCode 热题,敬请期待!
📌 推荐练习顺序:
-
先掌握单调栈(739)和双栈法(155)。
-
再挑战字符串解码(394)的嵌套逻辑。
-
最后尝试变体题(如"下一个更小元素"、"括号匹配"等)。
希望这篇博客对你刷题有所帮助!欢迎留言交流~