0%

1944. 队列中可以看到的人数

1944.队列中可以看到的人数

题目描述:

n 个人排成一个队列,从左到右 编号为 0n - 1 。给你以一个整数数组 heights ,每个整数 互不相同heights[i] 表示第 i 个人的高度。

一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 。更正式的,第 i 个人能看到第 j 个人的条件是 i < jmin(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1])

请你返回一个长度为 n 的数组 answer ,其中 answer[i] 是第 i 个人在他右侧队列中能 看到人数

数据范围:

$1\le n \le 10^5$

题解:

使用单调减栈维护,在单调减序列中,相邻的可以互相看到。每次遇到一个更高的,需要弹栈,比他矮的也都是可以看到他的。所以需要在弹栈的时候更新栈顶元素的能够看到的人数。

而且相邻的也可以看到。因此加入栈内时,也要更新他的前一个能看到的人数。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
auto optimize_cpp_stdio = []()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
class Solution
{
public:
const static int maxn = 1e5 + 10;
const static int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
vector<int> canSeePersonsCount(vector<int> &heights)
{
int n = heights.size();
vector<int> st(n);
vector<int> ans(n);
int top = -1;
for (int i = 0; i < n; ++i)
{
while (top >= 0 && heights[st[top]] <= heights[i])
{
ans[st[top]]++;
--top;
}
if (top >= 0)
ans[st[top]]++;
st[++top] = i;
}
return ans;
}
};