青训营 X 码上掘金->攒青豆

66 阅读2分钟

当青训营遇上码上掘金

经同学介绍参加了这次青训营,然后了解了青豆机制,就开始想白嫖了

0127EB7E.jpg

正好有个攒青豆的主题,所以就决定使用这个主题来换豆子了

这题之前做力扣的时候有刷到过,之前是没做出来,看了题解后记住了,今天回想了一会儿发现还是回忆起来了

思路

这个接豆子主要就是考虑一个边界问题,任意一个位置,只要你知道该位置的左边界和右边界就知道这个位置能装多少豆了。

一个位置的左边界一定是往左最大的一个数,右边界同理

拿题目的图当例图来讲解

image.png

[5,0,2,1,4,0,1,0,3]

对应位置的左边界即是从左到右遇到的最大的数

[5,5,5,5,5,5,5,5,5]

右边界同理

[5,4,4,4,4,3,3,3,3]

现在问题就迎刃而解了,比如我想知道某个位置能装多少豆,就3号位吧,它的高度为2,然后3号位左边界为5,右边界为4,那么很明显取较小的一个边界来算能装多少豆也就是4-2=2,其余同理。

[5,0,2,1,4,0,1,0,3]

[5,5,5,5,5,5,5,5,5]

[5,4,4,4,4,3,3,3,3]

一一对应下来就是下面这个

[0,4,2,3,0,3,2,3,0]

和为17

时间复杂度和空间复杂度都是O(n),因为要创建两个相同长度的数组存放左右边界,然后遍历3n次

public static void main(String []args) {
  Scanner scanner = new Scanner(System.in);
  ArrayList<Integer> height = new ArrayList<>();
  String s = scanner.nextLine();
  Scanner sc = new Scanner(s);
  while (sc.hasNextInt()){
    height.add(sc.nextInt());
  }
  //左边界数组
  Integer[] leftHeight = new Integer[height.size()];
  //右边界数组
  Integer[] rightHeight = new Integer[height.size()];
  //从左到右遍历,确定当前位置的最高左边界
  int max = 0;
  for (int i = 0; i < height.size(); i++) {
    if (height.get(i)>max){
      max = height.get(i);
    }
    leftHeight[i] = max;
  }
  //从右到左遍历,确定当前位置的最高右边界
  max = 0;
  for (int i = height.size()-1; i >= 0; i--) {
    if (height.get(i)>max){
      max = height.get(i);
    }
    rightHeight[i] = max;
  }
  int count = 0;
  for (int i = 0; i < height.size(); i++) {
    //指定左右边界中较小的一个
    int min = leftHeight[i]<rightHeight[i]?leftHeight[i] : rightHeight[i];
    count += min - height.get(i);

  }
  System.out.println(count);
}