[H单调栈] lc5196. 队列中可以看到的人数(单调栈+双周赛57_4)

Posted Ypuyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[H单调栈] lc5196. 队列中可以看到的人数(单调栈+双周赛57_4)相关的知识,希望对你有一定的参考价值。

1. 题目来源

链接:5196. 队列中可以看到的人数

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)的主要内容,如果未能解决你的问题,请参考以下文章

ACM数据结构-单调栈队列

模板 - 数据结构 - 单调队列/单调栈

Codeforces 547B. Mike and Feet[单调栈/队列]

单调队列单调栈优先队列模板

LC算法 LC [232. 用栈实现队列] LC [225. 用队列实现栈]

[M单调栈] lc1124. 表现良好的最长时间段(单调栈+新思路+反向遍历)