给定任意一个整数数组,组内元素无顺序,例如:[2,5,1,2,3,4,7,7,6] 以这个数组的值为高想象一些墙,如下图:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
蓝色的柱子的高度就是数组的值,
现假设这些柱子之间的空间可以用来盛水,如上面可盛水的部分如下图所示:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
现要求写一个算法能够满足任一数组 A ,求出他的盛水体积(一个表格代表1个单位)
可能的测试用例:
[2,5,1,2,3,1,7,5,6]=14 [2,4,1,5,3,1,7,5,6] = 10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
import java.util.List;
/**
*
*
*
* <code>{@link 数组盛水}</code>
*
* TODO : document me
*
* @author Administrator
* 该题目的关键之处就在于找到数组中的每个拐点,就是大于之前和之后的元素
* 也就是把数组分解成n个子序列,每个子序列是两端大于中间的每个数,但是容量又要取决于两端中较小的那个值,以及序列的宽度
*/
public class 数组盛水 {
public static void main(String[] args) {
int[] arr = { 2,4,1,5,3,1,7,5,6};
System.out.println(getWater(arr));
}
//先划分子序列
private static int getWater(int[] arr) {
int start = 0;
List list = new ArrayList();//把所有的子序列保存到一个list中
int totalWater = 0;
//子序列中的开始位start 和结束位end start和end(包含start和end)之间的数据保存成一个list temp 再把listtemp 保存到大的list中
while (start < arr.length - 2) {
while (start < arr.length - 2) {
if (arr[start] <= arr[start + 1]) {
start++;
} else {
break;
}
}
int end = start + 1;
for (int temp = end; temp < arr.length; temp++) {
if (arr[temp] >= arr[start]) {
end = temp;
break;
}
int max = arr[end];
if (max < arr[temp]) {
max = arr[temp];
end = temp;
}
}
// /
List tempList = new ArrayList();
for (int j = start; j <= end; j++) {
tempList.add(arr[j]);
}
list.add(tempList);
start = end;
}
/**
*
* 接下来就是从大list中拿出每个小list 进行计算 ,
*计算的时候要分情况 假如start< end 则从start开始计算
*否则 从end开始计算
*/
for (int i = 0; i < list.size(); i++) {
List l = (List) list.get(i);
int startWater = (Integer) l.get(0);
int endWater = (Integer) l.get(l.size() - 1);
if (startWater <= endWater) {//start< end 从start开始计算
for (int j = 0; j < l.size(); j++) {
if (startWater <= endWater) {
if ((Integer) l.get(j) < startWater) {
totalWater = totalWater
+ (startWater - (Integer) l.get(j));
}
}
}
} else {//start>end 从end开始计算
for (int k = l.size() - 1; k >= 0; k--) {
if ((Integer) l.get(k) < endWater) {
totalWater = totalWater
+ (endWater - (Integer) l.get(k));
}
}
}
}
return totalWater;
}
}