给定一个非负数的数组,代表一个容器。例如数组[0,1,0,2,1,0,1,3,2,1,2,1],就是
以下图形中黑色的部分。如果用这个容器接水的话,请问可以接多少水?还以这个数组为例,
可以接 6 格水,就是以下图形中蓝色的部分。
要求:实现时间复杂度 O(N),额外空间复杂度 O(1)的解法
public class Main{
public static void main(String[] args) {
int arr[]={0,1,0,2,1,0,1,3,2,1,2,1};
System.out.println(getWater(arr));
}
//逆向思维,先找到可能的最大值,然后看哪些位置的水能被算出来 该方法为最优解
public static int getWater(int[] arr){
if (arr==null||arr.length<1) {
return 0;
}
int value=0;
int leftMax=arr[0];
int rightMax=arr[arr.length-1];
int l=1;
int r=arr.length-2;
while (l<=r) {
if (leftMax<=rightMax) {//存水量就是当前位置左边最大值和右边最大值较小的那个值减去当前值,大于0的累加,小于0的记做0
value+=Math.max(0, leftMax - arr[l]);
leftMax=Math.max(leftMax, arr[l++]);
}else {
value+=Math.max(0, rightMax - arr[r]);
rightMax=Math.max(rightMax, arr[r--]);
}
}
return value;
}
}
总结左神的课,就是,拿到题目不要被题目的条条框框所限制,要跳出去思考,想办法改变规则,但改变后的规则和改变前的规则是等价的但是易于实现。
比方面试考察这种能力就是你能等价简化复杂业务的能力
这道题就是双指针问题的典型。
所有的题目都可以存在一个优化过程,比方看到log很自然要想到二分
n方是肯定不行的,优良解容易最优解难。最优解一定是针对某一个题得出的,而存在针对某一类问题的普遍的优化方法那么一定是比较简单的。
等价转换复杂问题
相关链接:http://blog.csdn.net/wdays83892469/article/details/78991195