1944. 队列中可以看到的人数(单调栈)

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

第一次尝试困难的题目,不过看评论区说好像配不上困难这个级别,但我做不出来😭

毫无技巧的暴力解法(超时)

class Solution {
public:
    vector<int> canSeePersonsCount(vector<int>& heights) {
        vector<int> result;
        int num=0;  //看到的人
        for(int i=0;i<heights.size()-1;i++){
            for(int j=i+1;j<heights.size();j++){
                if(j==i+1)num++;//当人就在他隔壁时,一定看得到
                else{
                    if(min(heights[i],heights[j])>*max_element(heights.begin()+i+1,heights.begin()+j))
                    num++;
                }
            }
            result.push_back(num);
            num=0;
        }
        result.push_back(0);//最后一个看到的一定是0个人
        return result;
    }
};

逻辑上没有错误,但是效率低下。

可以使用单调栈求解,要弄清楚单调栈,我们还是先做一下相对基础的题目,739. 每日温度(C++)单调栈的应用

逆序遍历 + 单调栈

官方解法

class Solution {
public:
    vector<int> canSeePersonsCount(vector<int>& heights) {
        int n = heights.size();
        vector<int> result(n);
        stack<int> s;   //可能看到的人的序列
        for(int i = n-1;i>=0;i--){ 
            while(!s.empty()){
                result[i]++;
                if(heights[i]>heights[s.top()]){
                    s.pop();    //因为当前的人的身高高于后面的人,所以再前的人也看不到后面的人,被挡住了。
                }else{
                    break;		//如果遇到高的,那后面就肯定看不到了,直接break;
                }
            }
            s.push(i);
        }
        return result;
    }
};

这里把!s.empty()heights[i]>heights[s.top()]条件分开。

因为之前遇到的单调栈是合在一起的,下面是我写的版本,两个条件不分开。

class Solution {
public:
	vector<int> canSeePersonsCount(vector<int>& heights) {
		int n = heights.size();
		vector<int> result(n);
		stack<int> s;   
		for (int i = n - 1; i >= 0; i--) {
			while (!s.empty()&& heights[i]>heights[s.top()]) {	//这里是遇到高的就跳出循环
				result[i]++;
				s.pop();
			}
			if(!s.empty())result[i]++;//所以这里还要算上那个高的。
			s.push(i);
		}
		return result;
	}
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值