11. 盛最多水的容器(LeetCode)
题目描述
给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器。
示例 1:

输入:[1,8,6,2,5,4,8,3,7]
输出:49
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。
条件分析
- 容纳最多的水,可以转换为求以下表达式的最大值,(right-left)*min(nums[left],nums[right]);
- 由于乘积取决于nums[left]和nums[rigth]的最小值,因此可以在保证初始left和right的差最大的情况下进行遍历,在找到一个值后,判断是left小还是right小,如果left小,则left+1,然后比较left+1的值和left的值,如果left+1小,继续找下一个left;如果right小,则right-1,然后比较right-1的值和right-1的值,如果right-1小,继续找下一个right
- 遍历过程中需要记住最大的乘积,直到left和right相遇
解题思路(指针对撞)
- 定义两个指针left和right分别指向字符串的首尾,进行交换,并各自相向移动一位,一直到两个指针相遇;
编码如下
public int maxArea(int[] height) {
int left = 0;
int right = height.length - 1;
int max = 0;;
while (left < right) {
int temp = getMax(height, left, right);
if (temp > max) {
max = temp;
}
if (height[left] <= height[right]) {
if (height[left+1] > height[left]) {
left++;
} else {
left++;
continue;
}
} else {
if (height[right - 1] > height[right]) {
right--;
} else {
right--;
continue;
}
}
}
return max;
}
public int getMax(int[] nums, int left, int right) {
int min = nums[left];
if (nums[left] > nums[right]) {
min = nums[right];
}
return min * (right - left);
}
浙公网安备 33010602011771号