最多水容器(M)
题目
给定n个非负整数a 1,a 2,...,a n,其中每个代表坐标(i,a i)处的一个点。绘制n条垂直线,使得线i的两个端点处于(i,a i)和(i,0)处。找到两条线,它们与x轴一起形成一个容器,使得容器包含最多的水。
注意:你可能不倾斜容器,n至少为2。
实现:
先看我的实现代码:
class Solution { public int maxArea(int[] height) { int area = 0; for(int i=0; i<height.length-1; i++){ for(int j=i+1; j<height.length; j++){ area = Math.max(area, Math.min(height[i], height[j])*(j-i)); } } return area; } }
为了找出最大面积,我的实现方法做了两次循环,所以,方法虽然是对的,但是时间超限。
下面看一个乍一看不对,但是仔细理解却是对的的实现方式,leetcode讨论区的:
public int maxArea(int[] height) { int left = 0, right = height.length - 1; int maxArea = 0; while (left < right) { maxArea = Math.max(maxArea, Math.min(height[left], height[right]) * (right - left)); if (height[left] < height[right]) left++; else right--; } return maxArea; }
以上这个方法只进行了一次遍历,不仔细考虑是会觉得这个方法是个错误方法,但是它却通过了,百思不得其解。
经过思考,是这样解释的:
限制这个容器容量的,除了底边长度,就是短边长度了,那么只需要每次改变短的那个边,保留长的那个边,那么上边的方法最后一定是一个会找到一个最长的边,以及其边上的边,这样实际上减少了遍历,但是理论上也找全了所有可能。