直方图的水量
)
自己的想法
每个水池一定是先发生递减,后发生递增的
所以用一个up数组记录数字的变化趋势
对于水池存在二种情况:
1、高地突出,拦截水流
2、水流从高处流下,但是出现了一个小突起,这个小突起对于后面都是高
下面展示一些 内联代码片
。
public int trap(int[] height) {//有漏洞,做的很不好
//水池一定是被先递减,后递增包围着的
if(height==null||height.length==0){
return 0;
}
int length = height.length;
int[] up = new int[length];
int[] max1 = new int[length];
Arrays.fill(up, -1);
// Arrays.fill(down, -1);
for (int i = 1; i < length; i++) {
if (height[i] >= height[i - 1]) {
up[i] = i;
}
}
max1[length-1]=height[length-1];
for(int i=length-2;i>=0;i--){
max1[i]=Math.max(height[i],max1[i+1]);
}
//遍历up数组
boolean up1 = false;
boolean down1 = false;
int maxPosition = -1;
int minPosition = -1;
int res = 0;
for (int i = 1; i < length; i++) {
if (up[i] != -1 && down1) {
//说明有递增,且前面有递减,找到最大的递增
minPosition = i;
up1 = true;
} else if (up[i] == -1 && i != 0) {
//说明递减
if (!down1) {
maxPosition = i - 1;
}
down1 = true;
}
if (up1 && down1 && (i == length - 1 || height[minPosition]>=height[maxPosition]||height[minPosition]==max1[minPosition])) {
up1 = false;
down1 = false;
int max = Math.min(height[maxPosition], height[minPosition]);
for (int h = maxPosition + 1; h < minPosition; h++) {
int num = max - height[h];
if (num > 0) {
res += num;
}
}
}
}
return res;
}
题解
动态规划,先前向遍历记录leftMax,然后后向遍历记录rightMax,最后计算重复
if(height==null||height.length==0){
return 0;
}
//利用动态规划做
int len=height.length;
int[] leftMax=new int[len];
int[] rightMax=new int[len];
//正向遍历:包括自身,左边最高
leftMax[0]=height[0];
rightMax[len-1]=height[len-1];
for(int i=1;i<len;i++){
leftMax[i]=Math.max(leftMax[i-1],height[i]);
}
//反向遍历,包括自身,右边最高
for(int i=len-2;i>=0;i--){
rightMax[i]=Math.max(rightMax[i+1],height[i]);
}
int res=0;
for(int i=0;i<len;i++){
res+=Math.min(leftMax[i],rightMax[i])-height[i];
}
return res;