题目
思路
答案和讨论请看这里:https://www.lintcode.com/problem/363/note/236598
或者直接看我的答案想思路
思路1:两种做法,单调栈和左右求最值,都不是很好想,要多练习
题型:双指针
观察题目:可知,基本常识:一个水桶能装多少水,取决于它的短板。
对于该题,某个位置的水能不能被累加,取决于左右两边最高的档板的位置。
因此:我们需要记录左右两边最高档板的高度。
思考2:
edge case的预先处理:如果heights == null 或者 heights.length < 2 存不住水,
直接返回0即可。
每一次 要么左指针右移,要么右指针左移,一定要移动一个。如果两个都不移动,循环出不去,
就是死循环。如果两个都移动,有可能会出现越界或者重复处理导致结果错误的情况发生。那么,
每一次该移动哪一个指针呢?
哪边的墙低,移动哪边。这样比较方便计算当前能够储存的水量。
参考代码
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* max water
* @param arr int整型一维数组 the array
* @return long长整型
*/
public long maxWater (int[] arr) {
/*
答案和讨论请看这里:https://www.lintcode.com/problem/363/note/236598
或者直接看我的答案想思路
思路1:两种做法,单调栈和左右求最值,都不是很好想,要多练习
题型:双指针
观察题目:可知,基本常识:一个水桶能装多少水,取决于它的短板。
对于该题,某个位置的水能不能被累加,取决于左右两边最高的档板的位置。
因此:我们需要记录左右两边最高档板的高度。
思考2:
edge case的预先处理:如果heights == null 或者 heights.length < 2 存不住水,直接返回0即可。
每一次 要么左指针右移,要么右指针左移,一定要移动一个。如果两个都不移动,循环出不去,就是死循环。如果两个都移动,有可能会出现越界或者重复处理导致结果错误的情况发生。那么,每一次该移动哪一个指针呢?
哪边的墙低,移动哪边。这样比较方便计算当前能够储存的水量。
*/
if (arr == null || arr.length < 2) return 0;
int n = arr.length;
int L = 1, R = n - 2, leftMax = arr[0], rightMax = arr[n - 1];
int water = 0;
while (L <= R) {
if (leftMax <= rightMax) {
water += Math.max(0, leftMax - arr[L]);
leftMax = Math.max(leftMax, arr[L++]);
} else {
water += Math.max(0, rightMax - arr[R]);
rightMax = Math.max(rightMax, arr[R--]);
}
}
return water;
}
}