1 题目描述
- 主题4:攒青豆
- 现有n个宽度为1的柱子,给出n个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)

2 思路
1、双指针
- 1)分析:
- 按列遍历,计算每一列左右两端最高高度,取其两者最低值,作为当列青豆的高度,宽度为1;收集每一列接收到的青豆,第一列和最后一列不计算;得到总的青豆数;
- 2)复杂度分析
- 时间复杂度o(n^2),空间复杂度o(1)
2、动态规划
- 1)分析:
- 采用双指针复杂度较高,因为每一列的左右高度都需要遍历一遍,其实存在重复计算,可用数组来存储每一列的左右高值,
vector<int>maxleft和vector<int>maxright
递归公式为maxleft[i] = max(height[i], maxleft[i - 1]);maxright[i] = max(height[i], maxright[i + 1]);
- 2)复杂度分析
- 时间复杂度o(n),空间复杂度O(n)
- 以空间换取时间
3、单调栈
- 1)分析:
- 自行维护一个单调栈,从栈底到栈头为从大到小顺序;
- 按行接青豆,遍历每一个值;
- 根据不同情况,对于栈出入采用不同操作;
- a.如果当前遍历的元素(柱子)高度小于栈顶元素的高度,就把这个元素加入栈中,因为栈里本来就要保持从小到大的顺序(从栈头到栈底)。
- b.如果当前遍历的元素(柱子)高度等于栈顶元素的高度,要跟更新栈顶元素,因为遇到相相同高度的柱子,需要使用最右边的柱子来计算宽度。
- c.如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了,栈顶和栈顶的下一个元素以及要入栈的三个元素来接水!
- 2)复杂度分析
- 时间复杂度o(n),空间复杂度o(n)
3 处理输入输出
int a;
vector<int>height;
while(cin >> a){
height.push_back(a);
}`
文章思路参考来源:
programmercarl.com/0042.%E6%8E…