Given n non-negative integers a1, a2, …, an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water. Note: You may not slant the container.
Solution
Two Pointers l and r:
start from two ends, keep updating maxsofar area
changing rule: if left’<’right then we know moving right makes no change(width decreases and min board is still left), so we need to move left pointer, vise versa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
publicintmaxArea(int[] height) {
if(height==null) return -1;
int curmax=-1, maxsofar=-1, l=0,r=height.length-1;
while(l<r){
curmax=(r-l)*Math.min(height[l],height[r]);
if(curmax>maxsofar){
maxsofar=curmax;
}
if(height[l]<height[r]){
//move r-- would never increase area with same l
int tmp=height[l];
while(l<r && height[l]<=tmp)
l++;
}
else{
int tmp=height[r];
while(l<r && height[r]<=tmp)
r--;
}
}
return maxsofar;
}
Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
Crazy Smart Solution
left[i] to store the largest to the left of i; right[i] to store the largest to the right of i. The min of these two, subtracted by A[i], determines how much water A[i] can hold remember to add up volume from 1 to n-2, since two sides cannot hold water.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
publicinttrap(int[] A) {
if (A == null || A.length == 0) {
return0;
}
int i, n=A.length,vol=0,max=0,left[]=newint[n],right[]=newint[n];