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。

条件分析


  1. 容纳最多的水,可以转换为求以下表达式的最大值,(right-left)*min(nums[left],nums[right]);
  2. 由于乘积取决于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
  3. 遍历过程中需要记住最大的乘积,直到left和right相遇

解题思路(指针对撞)


  1. 定义两个指针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);
}
posted @ 2021-07-08 18:27  咸与维新  阅读(63)  评论(0)    收藏  举报