队列中可以看到的人数——单调栈
原题在这里:
概述题意,给定一个数组x,返回一个数组y,y内每一个元素i值表示x从i开始左往右小于x[i]的递增元素数量。
(经典题目表示没能做出来有点菜)
analyse:
1.很自然地想到用单调栈来解题,但是思路不太对,从左往右构造单增栈:
对于每一个height:
如果当前stack.top更大,放入
如果当前stack.top更小:
出栈,且后序出栈ans+1(使用pre标记)
出栈,即更新ans下标
但是没能ac,这种使用pre标记没法解决断开的排列
比如:
4,1,2,3,5->得到[2,1,1,1,0],但是结果应该是[3,1,1,1,0]
code:
class Solution { public: vector<int> canSeePersonsCount(vector<int> &heights) { //单调栈的运用 /* 10:20 analyse: 对于每一个height 如果当前stack.top更大,放入 如果当前stack.top更小: 出栈,且后序出栈ans+1 出栈,即更新ans下标 */ int n = heights.size(), pre; vector<int> ans(n); stack<int> st; for (int i = 0; i < n; ++i) { while (st.size() && heights[st.top()] <= heights[i]) { //非空,更小,出栈 int x = st.top(); st.pop(); cout << x << "->" << heights[x] << " 不高于 " << i << "->" << heights[i] << ", pre=" << pre << endl; ans[x] = pre > x ? ans[pre] + 1 : 1; pre = x; } cout << "入栈:" << i << "->" << heights[i] << endl; st.push(i); pre = -1; } cout << "完美队列:" << endl; while (st.size()) { int x = st.top(); st.pop(); cout << x << "->" << heights[x] << ", pre=" << pre << endl; ans[x] = pre > x ? ans[pre] + 1 : 0; pre = x; } //不能解决断开的队列 return ans; } };
2.标准:从右往左构造单减栈:
对于每一个i:
如果栈非空循环处理:
i与st.top比较height:
i小,出循环
i大,y[i]+1,栈顶出栈(维护递减栈)
i入栈
code:
class Solution { public: vector<int> canSeePersonsCount(vector<int> &heights) { //单调栈的运用 /* 10:20 analyse: 构造一个逆序递减栈 */ int n = heights.size(), pre; vector<int> ans(n); stack<int> st; for (int i = n - 1; i >= 0; --i) { while (st.size()) { ans[i]++; if (heights[i] <= heights[st.top()]) break; st.pop(); } st.push(i); } return ans; } };
【Over】

浙公网安备 33010602011771号