单调栈用栈是为保证每个元素仅入栈出栈一次,实现o(n)时间复杂度;必须单调(如求下一更大元时栈底到顶严格递减),使新元素nums[i]能直接成为栈顶对应位置的答案。

单调栈的核心逻辑:为什么用栈,又为什么必须单调
单调栈不是为了“快”,而是为了把 O(n²) 的暴力扫描压到 O(n)。关键在“每个元素只入栈、出栈各一次”。栈里存的是下标(或值),但必须严格递减(对“下一个更大元素”问题,维护**从栈底到栈顶单调递减**的栈)。这样每次遇到一个新元素 nums[i],它天然就是栈顶元素的“下一个更大元素”——因为栈顶比它小,且中间没别的更大数挡路(否则早被弹出了)。
常见错误是反过来建递增栈,结果找的是“上一个更小元素”;或者栈里存值却忘了下标,导致没法回填答案数组。
标准实现模板:注意边界和初始化
典型场景:给定 vector<int>& nums</int>,返回等长 vector<int></int>,ans[i] 是 nums[i] 右侧第一个严格大于它的值,不存在则为 -1。
- 初始化
ans全为-1,避免漏填 - 栈里存下标(
stack<int> st</int>),方便索引nums和写ans - 遍历
i从0到n-1,对每个i,只要栈非空且nums[st.top()] ,就弹栈并设 <code>ans[st.top()] = nums[i] - 别忘了最后把
i压栈——它可能成为后面某个元素的答案
vector<int> nextGreaterElement(vector<int>& nums) {
int n = nums.size();
vector<int> ans(n, -1);
stack<int> st;
for (int i = 0; i <h3>环形数组怎么处理:取模不是万能的</h3>
<p>遇到“循环数组下一个更大元素”(如 <code>[1,2,1]</code> 中,最后一个 <code>1</code> 的答案是 <code>2</code>),不能简单跑两遍再取模下标——那样会错判“已访问过”。正确做法是模拟两轮遍历,但只用一个长度为 <code>n</code> 的答案数组,下标仍用 <code>i % n</code> 访问 <code>nums</code>,而栈中下标保持原始值(<code>0</code>~<code>n-1</code>)。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master"><img
src="https://img.php.cn/upload/skill/000/000/081/179051228971575.jpg" alt="C++ Code Review Master" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="overflowclass">C++ Code Review Master</a>
<p class="overflowclass">组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。</p>
</div>
<a rel="nofollow" href="/xiazai/skill5502" title="C++ Code Review Master" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<ul>
<li>循环次数设为 <code>2 * n - 1</code>,避免重复处理末尾</li>
<li>入栈条件加一道保护:<code>if (i ,防止同一位置压两次</code>
</li>
<li>判断是否已填过答案:靠 <code>ans[j] == -1</code>,不是靠栈里有没有这个下标</li>
</ul>
<h3>容易被忽略的细节:相等元素和空栈检查</h3>
<p>题目若要求“下一个**大于等于**”元素,比较符要改成 <code>;但“下一个更大”必须严格 <code>,否则 <code>[1,1,1]</code> 会把前两个 <code>1</code> 当作后一个的更大元素(实际不是)。</code></code></p>
<p>空栈检查必须写成 <code>!st.empty()</code>,不能只写 <code>st.size() > 0</code>(虽等价但易读性差);更关键的是,<code>st.top()</code> 前必须确保栈非空,否则运行时崩溃。</p>
<p>如果输入为空,<code>vector</code> 构造本身安全,但循环不执行——这点常被测试用例卡住,比如 <code>nextGreaterElement({})</code> 应返回空 <code>vector</code>。</p></int></int></int></int>C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










