leetcode 0042
说明
只是为了记录一下,不求多快,也不深究。
会简要描述思路,代码中不写注释。
如碰到不会做的用了别人代码会在博客中标出。
题目描述
思路
还是花了一些时间的,这题蛮有意思,代码一如既往的又臭又长。
findSpecialIndex(int[] height, List<Integer> specIdx)
这个方法是找出所有特殊的索引放到列表中,什么是特殊的索引呢?如果height[i]大于等于他两边的数,就认为是特殊的,能接多少雨水主要靠这一类数决定。
找到所有特殊数之后,还要进行过滤while (specSize != specIdx.size())
,就是代码中这个while循环来进行过滤的,一个特殊数如果他两边的特殊数都比他大,那能装多少雨水也不是他能决定的,从列表中剔除。
最后还要添加一些数,即使不是特殊数,也能决定装多少雨水,比如[5,4,1,2]中,4不是特殊数,但是他是’桶‘的一个边界,这类数分布在特殊数的两侧(或这类数本身的两侧),而且比某侧的特殊数更大,把这类数也放到列表中。
最后就是算一下列表中所有相邻数组成的矩形的面积,再减去这之间的数,就能得到装雨水的量了。
class Solution {
public int trap(int[] height) {
if (height.length < 3) {
return 0;
}
List<Integer> specIdx = new ArrayList<Integer>();
findSpecialIndex(height, specIdx);
if (specIdx.size() < 2) {
return 0;
}
int specSize = -1;
while (specSize != specIdx.size()) {
specSize = specIdx.size();
for (int i = 1; i < specIdx.size() - 1; i++) {
if (height[specIdx.get(i)] <= height[specIdx.get(i - 1)]
&& height[specIdx.get(i)] <= height[specIdx.get(i + 1)]) {
specIdx.remove(i);
}
}
}
if (specIdx.size() < 2) {
return 0;
}
for (int i = 0; i < specIdx.size(); i++) {
if (i != 0 && height[specIdx.get(i) - 1] > height[specIdx.get(i - 1)]) {
specIdx.add(i, specIdx.get(i) - 1);
i--;
}
if (i != specIdx.size() - 1 && height[specIdx.get(i) + 1] > height[specIdx.get(i + 1)]) {
specIdx.add(i + 1, specIdx.get(i) + 1);
}
}
int sum = 0;
for (int i = 0; i < specIdx.size() - 1; i++) {
int leftH = height[specIdx.get(i)];
int rightH = height[specIdx.get(i + 1)];
int tempHeight = leftH < rightH ? leftH : rightH;
int area = tempHeight * (specIdx.get(i + 1) - specIdx.get(i) - 1);
for (int j = specIdx.get(i) + 1; j < specIdx.get(i + 1); j++) {
area -= height[j];
}
sum += area;
}
return sum;
}
public void findSpecialIndex(int[] height, List<Integer> specIdx) {
for (int i = 0; i < height.length; i++) {
if (i == 0 && height[0] > height[1]) {
specIdx.add(i);
}
if (i == height.length - 1 && height[i] > height[i - 1]) {
specIdx.add(i);
}
if (i > 0 && i < height.length - 1 && height[i] >= height[i - 1] && height[i] >= height[i + 1]) {
specIdx.add(i);
}
}
}
}