当青训营遇上码上掘金 - 攒青豆

62 阅读2分钟
  • 当青训营遇上码上掘金

1 题目描述

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

image.png

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…