11. 盛最多水的容器
这种问题我们是需要考虑的。
这是一种典型的,目标值是一个乘积,两维的乘积,于是如果我们大海捞针,就需要完全遍历,但一般的二维,我们都可以考虑以下方式:
- 把一个维度先排序,然后在考虑是否有优化手段,也就是某些地方剪枝
回到本题,显然乘积=x*长度,x是两端中更小的那个值
长度是天然的有序的,于是我们就考虑从最长的来看,也就是去端点最左和最右。
于是就得到了,len最长的情况下的值,接下来的len必然是减小的,于是就知道如果x减小或者不变,是不可能得到更大值的,于是我们将更小的那一端移动,如果右端小,右端指针往左移动;左端小,左端指针往右移动。
下面我们给出了两种写法,第一种leetcode是5ms,第二种是3ms。
这就是我们代码优化的意义,对代码重构。
第一种比第二种多了一个两端大小判断,我们应该优化到里面去。
写法一:
public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int MAX = -1;
while (left <= right) {
MAX = Math.max((right - left) * Math.min(height[left], height[right]), MAX);
if (height[right] < height[left]) right--;
else left++;
}
return MAX;
}
写法二:
public int maxArea(int[] height) {
int left = 0, right = height.length - 1;
int MAX = -1;
while (left <= right) {
if (height[right] < height[left]) {
MAX = Math.max((right - left) * height[right], MAX);
right--;
}
else {
MAX = Math.max((right - left) * height[left], MAX);
left++;
}
}
return MAX;
}