当青训营遇上码上掘金
经同学介绍参加了这次青训营,然后了解了青豆机制,就开始想白嫖了
正好有个攒青豆的主题,所以就决定使用这个主题来换豆子了
这题之前做力扣的时候有刷到过,之前是没做出来,看了题解后记住了,今天回想了一会儿发现还是回忆起来了
思路
这个接豆子主要就是考虑一个边界问题,任意一个位置,只要你知道该位置的左边界和右边界就知道这个位置能装多少豆了。
一个位置的左边界一定是往左最大的一个数,右边界同理
拿题目的图当例图来讲解
[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);
}