当青训营遇上码上掘金。
题目解析
给定数组,每个数是从左到右的柱子的高度,求的是能接住多少青豆,也就是上图中青豆所占的正方形个数。
解法思路:按行求
顾名思义,就是先求高度为1的这一行接住的青豆,再求高度为2的这一行接住的青豆,再求高度为3的这一行的青豆,一行一行的求。
整体思路思路:求高度为i的一行的青豆,需要从左到右遍历一遍,如果当前的柱子高度小于i,并且两边的柱子高度大于等于i,那么这个地方是可以接住青豆的,将青豆数加1。
求高度为i的一行的青豆,首先定义一个变量temp,用来记录这一行从左到右的每个正方形是否能接住青豆,初始化为0。现在开始从左到右遍历temp,注意,需要遇到高度大于i的时候才开始更新temp,否则temp一直为0。这是因为,如果从左边开始柱子的高度一直为0的话,是没办法接住青豆的。遇到高度大于i的柱子之后,遇到柱子高度小于i,就把temp加1,再次遇到高度大于i的柱子时,把temp加入到最终答案ans中,并且重置temp为0,继续遍历。
先遍历第一行:
数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于1,temp++,柱子高度大于1,ans = ans + temp,temp = 0。
初始化:temp = 0, ans = 0。
height[0] = 5 >= 1,开始更新。
heigth[1] = 0 < 1,temp++ = 1。
heigth[2] = 2 >= 1,ans = ans + temp = 1,temp = 0。
heigth[3] = 1 >= 1,ans = ans + temp = 1,temp = 0。
heigth[4] = 4 >= 1,ans = ans + temp = 1,temp = 0。
heigth[5] = 0 < 1,temp++ = 1。
heigth[6] = 1 >= 1,ans = ans + temp = 2,temp = 0。
heigth[7] = 0 < 1,temp++ = 1。
heigth[8] = 3 >= 1,ans = ans + temp = 3,temp = 0。
第一行结束遍历时,ans = 3。
再遍历第二行:
数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于2,temp++,柱子高度大于2,ans = ans + temp,temp = 0。
height[0] = 5 >= 2,开始更新。
heigth[1] = 0 < 2,temp++ = 1。
heigth[2] = 2 >= 2,ans = ans + temp = 4,temp = 0。
heigth[3] = 1 < 2,temp++ = 1。
heigth[4] = 4 >= 2,ans = ans + temp = 5,temp = 0。
heigth[5] = 0 < 2,temp++ = 1。
heigth[6] = 1 < 2,temp++ = 2。
heigth[7] = 0 < 2,temp++ = 3。
heigth[8] = 3 >= 2,ans = ans + temp = 8,temp = 0。
第二行结束遍历时,ans = 8。
再遍历第三行:
数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于3,temp++,柱子高度大于3,ans = ans + temp,temp = 0。
height[0] = 5 >= 3,开始更新。
heigth[1] = 0 < 3,temp++ = 1。
heigth[2] = 2 < 3,temp++ = 2。
heigth[3] = 1 < 3,temp++ = 3。
heigth[4] = 4 >= 3,ans = ans + temp = 11,temp = 0。
heigth[5] = 0 < 3,temp++ = 1。
heigth[6] = 1 < 3,temp++ = 2。
heigth[7] = 0 < 3,temp++ = 3。
heigth[8] = 3 >= 3,ans = ans + temp = 14,temp = 0。
第三行结束遍历时,ans = 14。
再遍历第四行:
数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于4,temp++,柱子高度大于4,ans = ans + temp,temp = 0。
height[0] = 5 >= 4,开始更新。
heigth[1] = 0 < 4,temp++ = 1。
heigth[2] = 2 < 4,temp++ = 2。
heigth[3] = 1 < 4,temp++ = 3。
heigth[4] = 4 >= 4,ans = ans + temp = 17,temp = 0。
heigth[5] = 0 < 4,temp++ = 1。
heigth[6] = 1 < 4,temp++ = 2。
heigth[7] = 0 < 4,temp++ = 3。
heigth[8] = 3 < 4,temp++ = 4。
第四行结束遍历时,ans = 17。
注意,这里遍历到最后,虽然temp = 4,但是由于后面没有柱子高度大于4了,所以不更新ans。
最后遍历第五行:
数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于5,temp++,柱子高度大于5,ans = ans + temp,temp = 0。
height[0] = 5 >= 5,开始更新。
heigth[1] = 0 < 5,temp++ = 1。
heigth[2] = 2 < 5,temp++ = 2。
heigth[3] = 1 < 5,temp++ = 3。
heigth[4] = 4 < 5,temp++ = 4。
heigth[5] = 0 < 5,temp++ = 5。
heigth[6] = 1 < 5,temp++ = 6。
heigth[7] = 0 < 5,temp++ = 7。
heigth[8] = 3 < 5,temp++ = 8。
第四行结束遍历时,ans = 17。
注意,这里遍历到最后,虽然temp = 8,但是由于后面没有柱子高度大于5了,所以不更新ans。
所以最终的ans = 17。
代码如下:
/**
* 支持 import Java 标准库 (JDK 1.8)
*/
import java.util.*;
/**
* 注意:目前 Java 代码的入口类名称必须为 Main(大小写敏感)
*/
public class Main {
public static int trap(int[] height) {
int sum = 0;
int max = getMax(height);//找到最大的高度,以便遍历。
for (int i = 1; i <= max; i++) {
boolean isStart = false; //标记是否开始更新 temp
int temp_sum = 0;
for (int j = 0; j < height.length; j++) {
if (isStart && height[j] < i) {
temp_sum++;
}
if (height[j] >= i) {
sum = sum + temp_sum;
temp_sum = 0;
isStart = true;
}
}
}
return sum;
}
public static int getMax(int[] height) {
int max = 0;
for (int i = 0; i < height.length; i++) {
if (height[i] > max) {
max = height[i];
}
}
return max;
}
public static void main(String []args) {
int[] height = {5,0,2,1,4,0,1,0,3};
int ans = trap(height);
System.out.println(ans);
}
}