Container With Most Water
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.
分析
题意是:给出一个整形数组a1,a2...,an,数组的每个元素表示一个坐标(i, ai)。对每个坐标(i, ai)和(i, 0),连接一条线,n个元素就有n条线,再加上X坐标轴构成了一个容器。要求找到两条竖线,使之和X轴构成的小容器能够容纳最多的水。
要理解题意,必须先意识到水的特点是总是保持一个矩形,以最小的height那条边作为矩形的高。
* 这是一道双指针/滑动窗口的题型,即利用两个指针对一个数组或链表进行扫描。
* 扫描方式有以不同速度从头向尾扫描,或者分别从头和尾向中间扫描。
* 这道题最简单的做法是用第一种扫描方式,两层for循环,复杂度O(N^2),但是leetcode判断超时;
* AC的解法使用了分别从头和尾向中间扫描的方式,复杂度为O(N),需要注意的是判断终止条件。
Code
Code 1:O(N*N)算法(Time Limit Exceeded)
class Solution {
public :
/*
* 因为水的特性,在容器里总是以矩形存在的,所以最小的height才是高
* 最简单的方法是设置两层for循环,枚举所有的左边height和右边height,求出所有面积,得出最大面积。
* 这个算法复杂度O(N^2),leetcode平台判断为Time Limit Exceeded超时。
* */
int maxArea ( vector < int > & height ) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if ( height . size () < 2 )
return 0 ;
int maxArea = 0 ;
int tempArea = 0 ;
for ( int left = 0 ; left < height . size () - 1 ; left ++ )
{
for ( int right = left + 1 ; right < height . size (); right ++ )
{
tempArea = std :: min ( height [ left ], height [ right ]) * ( right - left );
if ( tempArea > maxArea )
maxArea = tempArea ;
}
}
return maxArea ;
}
};
Code 2:O(N)算法(Accepted)
class Solution {
public :
/*
* 这是一道双指针/滑动窗口的题型,即利用两个指针对一个数组或链表进行扫描。
* 扫描方式有以不同速度从头向尾扫描,或者分别从头和尾向中间扫描。
* 这道题最简单的做法是用第一种扫描方式,两层for循环,复杂度O(N^2),但是leetcode判断超时;
* 下面的解法使用了分别从头和尾向中间扫描的方式,复杂度为O(N),需要注意的是判断终止条件。
*
* */
int maxArea ( vector < int > & height ) {
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if ( height . size () < 2 )
return 0 ;
int maxArea = 0 ;
int tempArea = 0 ;
int left = 0 , right = height . size () - 1 ;
while ( left < right )
{
//水的特点是总是保持一个矩形,以最小的height那条边作为矩形的高
tempArea = ( right - left ) * std :: min ( height [ left ], height [ right ]);
maxArea = std :: max ( tempArea , maxArea );
//这是整段代码的关键点,指针的移动条件
if ( height [ left ] <= height [ right ])
left ++ ;
else
right -- ;
}
return maxArea ;
}
};