题目描述:
有 n
个人排成一个队列,从左到右 编号为 0
到 n - 1
。给你以一个整数数组 heights
,每个整数 互不相同,heights[i]
表示第 i
个人的高度。
一个人能 看到 他右边另一个人的条件是这两人之间的所有人都比他们两人 矮 。更正式的,第 i
个人能看到第 j
个人的条件是 i < j
且 min(heights[i], heights[j]) > max(heights[i+1], heights[i+2], ..., heights[j-1])
。
请你返回一个长度为 n
的数组 answer
,其中 answer[i]
是第 i
个人在他右侧队列中能 看到 的 人数 。
数据范围:
1≤n≤105
题解:
使用单调减栈维护,在单调减序列中,相邻的可以互相看到。每次遇到一个更高的,需要弹栈,比他矮的也都是可以看到他的。所以需要在弹栈的时候更新栈顶元素的能够看到的人数。
而且相邻的也可以看到。因此加入栈内时,也要更新他的前一个能看到的人数。
代码:
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; } };
|
v1.5.1