Container with most water

来源:互联网 发布:sql数据库紧急模式 编辑:程序博客网 时间:2024/06/08 02:38

首先原题描述如下:

Given n non-negative integers a1a2, ...,an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of linei is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

 

题目意思就不翻译了,大概是要找到条纵线然后这两条线以及X轴构成的容器能容纳最多的水。

下面以例子:   [4,6,2,6,7,11,2] 来讲解。

1.首先假设我们找到能取最大容积的纵线为 i , j (假定i<j),那么得到的最大容积 C = min( ai , aj ) * ( j- i) ;

2.下面我们看这么一条性质:

①: 在 j 的右端没有一条线会比它高! 假设存在 k |( j<k && ak > aj) ,那么  由 ak> aj,所以 min( ai,aj, ak) =min(ai,aj) ,所以由i, k构成的容器的容积C' = min(ai,aj ) * ( k-i) > C,与C是最值矛盾,所以得证j的后边不会有比它还高的线;

②:同理,在i的左边也不会有比它高的线;

这说明什么呢?如果我们目前得到的候选: 设为 x, y两条线(x< y),那么能够得到比它更大容积的新的两条边必然在  [x,y]区间内并且 ax' > =ax , ay'>= ay;

3.所以我们从两头向中间靠拢,同时更新候选值;在收缩区间的时候优先从  x, y中较小的边开始收缩;

 

直观的解释是:容积即面积,它受长和高的影响,当长度减小时候,高必须增长才有可能提升面积,所以我们从长度最长时开始递减,然后寻找更高的线来更新候补;

 

代码如下:

[html] view plaincopy
  1. class Solution {  
  2. public:  
  3.     int maxArea(vector<int> &h) {  
  4.         // Start typing your C/C++ solution below  
  5.         // DO NOT write int main() function  
  6.         int res=0;  
  7.         int n = h.size();  
  8.         int l=0,r=n-1;  
  9.         while(l<r)  
  10.         {  
  11.             res=max(res,min(h[l],h[r])*(r-l));  
  12.             if (h[l]<h[r])  
  13.             {  
  14.                 int k=l;  
  15.                 while(k<r&&h[k]<=h[l])  
  16.                     k++;  
  17.                 l=k;  
  18.                 }  
  19.             else  
  20.             {  
  21.                 int k=r;  
  22.                 while(k>l&&h[k]<=h[r])  
  23.                     k--;  
  24.                 r=k;  
  25.              }  
  26.         }  
  27.         return res;  
  28.     }  
  29. };  

大数据 88 ms A过。


public int maxArea(int[] height) {if (height == null || height.length < 2) {return 0;} int max = 0;int left = 0;int right = height.length - 1; while (left < right) {max = Math.max(max, (right - left) * Math.min(height[left], height[right]));if (height[left] < height[right])left++;elseright--;} return max;}


转自:http://blog.csdn.net/a83610312/article/details/8548519

http://www.programcreek.com/2014/03/leetcode-container-with-most-water-java/

0 0
原创粉丝点击