思路:
class Solution {
public:
vector<int> canSeePersonsCount(vector<int>& heights) {
int len = heights.size();
vector<int> answer(len); //记录每个人可以看到几个人
for(int i = 0; i < len - 1; i++){ //遍历除最后一个人外的每一个人,因为最后一个人能见人数肯定是0
if(heights[i + 1] >= heights[i]){answer[i] = 1;continue;} //如果右边第一个人就比自己高,直接记为1,跳过此次循环
answer[i] = 1; //记录当前人可见人数,因为已经判断右边第一个人,所以初值为1
int t = heights[i + 1]; //记录左边的最高人,初值为当前人右边的人
for(int j = i + 2; j < len; j++){ //从当前人右边第二个开始判断是否可见
if(heights[j] >= heights[i]){answer[i]++;break;} //遇到比当前人更高的人,记录,并退出遍历
if(heights[j] < t) continue; //如果左边有比自己更高的人,则跳过
t = heights[j]; //如果没有,则自己为当前最高的,更换最高人
answer[i]++; //记录,能到这里,说明满足条件
}
}
return answer;
}
};
假设输入为heights = [10,6,8,5,11,9],对于这个输入——
i | h[i] | 入栈前 | 入栈后 | 可见人数 | 解释 |
5 | 9 | [] | [9] | 0 | |
4 | 11 | [9] | [11] | 1 | 11挡住9,弹出9 |
3 | 5 | [11] | [11,5] | 1 | |
2 | 8 | [11,5] | [11,8] | 2 | 8挡住5,弹出5 |
1 | 6 | [11,8] | [11,8,6] | 1 | |
0 | 10 | [11,8,6] | [11,10] | 3 | 10挡住8,6,弹出8,6 |
代码:
class Solution {
public:
vector<int> canSeePersonsCount(vector<int>& heights) {
int len = heights.size();
stack<int> stack; //栈
vector<int> answer(len); //记录可见人数
for(int i = len - 1; i >= 0; i--){ //从最后一个开始压栈
while(!stack.empty() && stack.top() < heights[i]){ //如果栈不为空且栈顶元素小于当前要压栈元素
stack.pop(); //弹栈
answer[i]++; //记录
}
if(!stack.empty()) answer[i]++; //若栈不为空,则代表当前要压栈元素后边还有一个比之更高的人可见,记录
stack.push(heights[i]); //压栈
}
return answer;
}
};
??