Container With Most Water

来源:互联网 发布:javascript语法大全 编辑:程序博客网 时间:2024/06/05 18:54

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.
思路:刚一看到这道题,我把它想复杂了,这道题是要求寻找两根线,求这两根线与x轴一起围城的面积最大(盛水最多),而不需要考虑这两个线中间其他线的情况(如果考虑两根线之间的情况,题目相对复杂些).先说一下不考虑的情况,也就是本题的情况:
可以设两个指针i,j分别指向数组的头和尾,如果height[i]

class Solution {public:    int maxArea(vector<int>& height) {        int len = height.size();        if(height.empty() || len < 2)            return 0;        int maxArea = 0;        int i = 0, j = len - 1;        while(i < j){            int tmpArea = min(height[i], height[j]) * (j - i);            if(height[i] < height[j])                i++;            else                j--;            if(maxArea < tmpArea)                maxArea = tmpArea;        }        return maxArea;    }};

如果考虑这两根线中间其他线的情况,问题相对复杂些,可以考虑使用动态规划算法来求解,记water[i][j]表示height[i]~height[j]与x轴装水的值,那么有
water[i][j+1] = water[i][k] + water[k][j+1],而这个k的位置很关键,k是从j+1到i之间首次height[k]>=height[j+1]时的位置,至于为什么是这个位置,可以画图想想,代码如下:

int maxArea(int *height, int heightSize){    if(height == NULL || heightSize < 2)        return 0;    int max = 0, i, j, k;    int **water = (int **)malloc(sizeof(int *) * heightSize);    for(i = 0; i < heightSize; ++i){        water[i] = (int *)malloc(sizeof(int) * heightSize);        memset(water[i], 0, heightSize);    }    for(i = 0; i < heightSize - 1; ++i){        for(j = i + 1; j < heightSize; ++j){            if(water[i][j])//已经求过了                continue;            k = j - 1;            while(k >= i){                if(height[j] > height[k])                    k--;                else{                    water[k][j] = height[j] * (j - k);                    water[i][j] = water[i][k] + water[k][j];                    break;                }            }            if(k < i){                water[i][j] = height[i] * (j - i);            }            if(max < water[i][j])                max = water[i][j];        }    }    return max;}
0 0