「青训营 X 码上掘金」主题创作活动-攒青豆的一种简单求解思路

36 阅读3分钟

当青训营遇上码上掘金。

image.png

题目解析

给定数组,每个数是从左到右的柱子的高度,求的是能接住多少青豆,也就是上图中青豆所占的正方形个数。

解法思路:按行求

顾名思义,就是先求高度为1的这一行接住的青豆,再求高度为2的这一行接住的青豆,再求高度为3的这一行的青豆,一行一行的求。

整体思路思路:求高度为i的一行的青豆,需要从左到右遍历一遍,如果当前的柱子高度小于i,并且两边的柱子高度大于等于i,那么这个地方是可以接住青豆的,将青豆数加1

求高度为i的一行的青豆,首先定义一个变量temp,用来记录这一行从左到右的每个正方形是否能接住青豆,初始化为0。现在开始从左到右遍历temp,注意,需要遇到高度大于i的时候才开始更新temp,否则temp一直为0。这是因为,如果从左边开始柱子的高度一直为0的话,是没办法接住青豆的。遇到高度大于i的柱子之后,遇到柱子高度小于i,就把temp1,再次遇到高度大于i的柱子时,把temp加入到最终答案ans中,并且重置temp0,继续遍历。

先遍历第一行: image.png


数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于1temp++,柱子高度大于1ans = ans + temp,temp = 0

初始化:temp = 0, ans = 0

height[0] = 5 >= 1,开始更新。

heigth[1] = 0 < 1temp++ = 1

heigth[2] = 2 >= 1ans = ans + temp = 1temp = 0

heigth[3] = 1 >= 1ans = ans + temp = 1temp = 0

heigth[4] = 4 >= 1ans = ans + temp = 1temp = 0

heigth[5] = 0 < 1temp++ = 1

heigth[6] = 1 >= 1ans = ans + temp = 2temp = 0

heigth[7] = 0 < 1temp++ = 1

heigth[8] = 3 >= 1ans = ans + temp = 3temp = 0

第一行结束遍历时,ans = 3

再遍历第二行: image.png


数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于2temp++,柱子高度大于2ans = ans + temp,temp = 0

height[0] = 5 >= 2,开始更新。

heigth[1] = 0 < 2temp++ = 1

heigth[2] = 2 >= 2ans = ans + temp = 4temp = 0

heigth[3] = 1 < 2temp++ = 1

heigth[4] = 4 >= 2ans = ans + temp = 5temp = 0

heigth[5] = 0 < 2temp++ = 1

heigth[6] = 1 < 2temp++ = 2

heigth[7] = 0 < 2temp++ = 3

heigth[8] = 3 >= 2ans = ans + temp = 8temp = 0

第二行结束遍历时,ans = 8

再遍历第三行: image.png


数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于3temp++,柱子高度大于3ans = ans + temp,temp = 0

height[0] = 5 >= 3,开始更新。

heigth[1] = 0 < 3temp++ = 1

heigth[2] = 2 < 3temp++ = 2

heigth[3] = 1 < 3temp++ = 3

heigth[4] = 4 >= 3ans = ans + temp = 11temp = 0

heigth[5] = 0 < 3temp++ = 1

heigth[6] = 1 < 3temp++ = 2

heigth[7] = 0 < 3temp++ = 3

heigth[8] = 3 >= 3ans = ans + temp = 14temp = 0

第三行结束遍历时,ans = 14

再遍历第四行: image.png


数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于4temp++,柱子高度大于4ans = ans + temp,temp = 0

height[0] = 5 >= 4,开始更新。

heigth[1] = 0 < 4temp++ = 1

heigth[2] = 2 < 4temp++ = 2

heigth[3] = 1 < 4temp++ = 3

heigth[4] = 4 >= 4ans = ans + temp = 17temp = 0

heigth[5] = 0 < 4temp++ = 1

heigth[6] = 1 < 4temp++ = 2

heigth[7] = 0 < 4temp++ = 3

heigth[8] = 3 < 4temp++ = 4

第四行结束遍历时,ans = 17

注意,这里遍历到最后,虽然temp = 4,但是由于后面没有柱子高度大于4了,所以不更新ans

最后遍历第五行: image.png


数组:height = [5,0,2,1,4,0,1,0,3]
更新原则:柱子高度小于5temp++,柱子高度大于5ans = ans + temp,temp = 0

height[0] = 5 >= 5,开始更新。

heigth[1] = 0 < 5temp++ = 1

heigth[2] = 2 < 5temp++ = 2

heigth[3] = 1 < 5temp++ = 3

heigth[4] = 4 < 5temp++ = 4

heigth[5] = 0 < 5temp++ = 5

heigth[6] = 1 < 5temp++ = 6

heigth[7] = 0 < 5temp++ = 7

heigth[8] = 3 < 5temp++ = 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);

}

}