Processing math: 100%

Monday, November 17, 2014

Container with most water


Leetcode link:
Q:
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. 


A:
Given line i and line j, one can easily come up with: Area[i][j]=min(height[i],height[j])(ji)

So an O(n2) solution is fairly easy to get.


To decrease the time complexity, tricks and pruning are all what you need. Suppose we found an solution from i to j (i<j), and we assume height[i]<height[j]. Then height[i] is dominant, which means if we decrease j, there will be no area larger than Area[i][j]. This should be very easy to verify.


With this pruning, in order to investigate all possible i and j combinations, we start with i=0 and j=height.size()1 and shrink i and j inward, resulting the following simple code:


int maxArea(vector<int> &height) {
    if(height.size() <= 1) return 0;
    // idea of this program: If found one candidate [A[i], A[j]], 
    // if A[i] < A[j] then A[i] is dominate. all [A[i], A[j-k]] (k>0) 
    // will not generate area larger than [A[i], A[j]]. The only 
    // candidates can be achieved by moving j.
    int low, high;
    low = 0;
    high = height.size()-1;
    int maxarea = min(height[high], height[low]) * (high-low);
    while(low != high) {
        maxarea = max(maxarea, min(height[high], height[low]) * (high-low));
        if(height[low] < height[high]) low++;
        else high--;
    }
    return maxarea;
}

No comments:

Post a Comment