[H单调栈] lc5196. 队列中可以看到的人数(单调栈+双周赛57_4)
Posted Ypuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[H单调栈] lc5196. 队列中可以看到的人数(单调栈+双周赛57_4)相关的知识,希望对你有一定的参考价值。
1. 题目来源
2. 题目解析
单调栈裸题。
和朴素的找他右边的第一个比它高的数不太一样,因为对于样例一而言,编号 3 是看不到的。
但不难发现,从后至前维护一个单调递增栈,对于当前元素而言,比它小的栈中元素就是它能看到的元素,也就是维护单调递增栈时的出栈元素个数。故维护过程中记录下出栈元素个数即可。
注意,当栈不为空时,说明栈中存在一个比当前元素还高的元素,它也是能看到的,所以需要将出栈个数 +1,这才是当前元素所能看到的所有元素个数。
最后记得反转一下整个答案数组,因为是倒着做的。
本次双周赛异常简单,都是些基本算法和裸题…手速场了属于是。
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
代码:
我的代码。
思路差不多,关于两边端点的问题,可以使用标记数组处理,即对差分过的端点位置打个标记,最后直接求就行了。大同小异吧。
class Solution {
public:
vector<int> canSeePersonsCount(vector<int>& h) {
int n = h.size();
stack<int> stk;
vector<int> res;
for (int i = n - 1; ~i; i -- ) {
int cnt = 0;
while (stk.size() && h[stk.top()] <= h[i]) stk.pop(), cnt ++ ;
if (stk.size()) res.push_back(cnt + 1);
else res.push_back(cnt);
stk.push(i);
}
reverse(res.begin(), res.end());
return res;
}
};
liouzhou_101 大佬的代码。
思路差不多,但是实现更加简洁。
class Solution {
public:
vector<int> canSeePersonsCount(vector<int>& h) {
int n = h.size();
vector<int> v;
vector<int> res(n);
for (int i = n - 1; i >= 0; --i)
{
while (!v.empty() && v.back() < h[i])
{
v.pop_back();
res[i] += 1;
}
if (!v.empty()) res[i] += 1;
v.push_back(h[i]);
}
return res;
}
};
以上是关于[H单调栈] lc5196. 队列中可以看到的人数(单调栈+双周赛57_4)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces 547B. Mike and Feet[单调栈/队列]