一、题目
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 256M,其他语言512M
小Q在周末的时候和他的小伙伴来到大城市逛街,一条步行街上有很多高楼,共有n座高楼排成一行。
小Q从第一栋一直走到了最后一栋,小Q从来都没有见到这么多的楼,所以他想知道他在每栋楼的位置处能看到多少栋楼呢?(当前面的楼的高度大于等于后面的楼时,后面的楼将被挡住)
输入例子1:
[5,3,8,3,2,5]
输出例子1:
[3,3,5,4,4,4]
例子说明1:
当小Q处于位置3时,他可以向前看到位置2,1处的楼,向后看到位置4,6处的楼,加上第3栋楼,共可看到5栋楼。当小Q处于位置4时,他可以向前看到位置3处的楼,向后看到位置5,6处的楼,加上第4栋楼,共可看到4栋楼。
二、思路
1、总体思路用单调栈(单调递减)来解决
2、因为是既可以往前看又可以往后看,所在楼栋是可以看到的,还有所在楼栋的前面和后面一栋也是可以看到的
3、设计两个单调栈,一个单调栈从前往后,另一个从后往前;
单调栈s1从前往后单调递减(前面有高楼栋,后面的低楼栋就去除掉)
单调栈s2从后往前单调递减
4、将s2转置,相当于在同一楼栋位置处,s1是往前看的,s2是往后看的,输出时s1对应的值+s2对应的值+1(所在的楼栋本身)
三、C++代码实现
class Solution
{
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param heights int整型vector
* @return int整型vector
*/
vector<int> findBuilding(vector<int> &heights)
{
//单调栈
stack<int> s1;
stack<int> s2;
//存储看到楼栋个数的容器
vector<int> a;
vector<int> b;
for (int i = 0, j = heights.size() - 1; i < heights.size(), j >= 0; i++, j--)
{
//添加单调栈中的个数到容器中
a.emplace_back(s1.size());
b.emplace_back(s2.size());
//单调栈操作
while (!s1.empty() && heights[i] >= s1.top())
{
s1.pop();
}
while (!s2.empty() && heights[j] >= s2.top())
{
s2.pop();
}
//添加新元素
s1.push(heights[i]);
s2.push(heights[j]);
}
//转置b
reverse(b.begin(), b.end());
vector<int> output;
for (int i = 0; i < heights.size(); i++)
{
output.emplace_back(a[i] + b[i] + 1);
}
return output;
}
};