LeetCode 数组系列 ~盛最多水的容器

73 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第25天,点击查看活动详情

概述

数组算是一个并不复杂的数据结构,但就是这个,面试官就能在面试过程中考察出很多东西来。例如经典的排序问题,二分搜索,滑动窗口等等,都是在数组这种最基础等数据结构中处理问题的。

我们做数组类算法问题的时候,常常需要定义一个变量,明确该变量的意义,并不停的维护这个变量,也需要特别注意初始值边界问题。

题目

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例

image.png

输入:[1,8,6,2,5,4,8,3,7]
输出:49 
解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49
输入: height = [1,1]
输出: 1

提示

  • n == height.length
  • 2 <= n <= 10^5
  • 0 <= height[i] <= 10^4

代码实现

双指针

这道题也可以采用双指针的直接,具体步骤如下:

  1. 定义两个指针分别指向数组首尾两个位置;
  2. 定义一个变量保存每次更新的最大值;
  3. 两个指针逐位比较,向中间靠拢;
  4. 计算得出容器的长度;
  5. 比较两边的宽度,取短的一边;
  6. 计算容器面积,并更新结果,同时移动指针;
  7. 结束循环,返回结果。
class Solution {
    public int maxArea(int[] heights) {
        // 定义两个指针分别指向数组首尾两个位置
        int left = 0, right = heights.length - 1;
        // 结果变量
        int max = 0;
        // 向中间靠拢
        while(left < right){
            // 得出容器的长度
            int height = right - left;
            // 比较两边的宽度,取短的一边
            if(heights[left] < heights[right]){
                // 计算,赋值,移动指针
                max = Math.max(max, heights[left] * height);
                ++left;
            }else{
                // 计算,赋值,移动指针
                max = Math.max(max, heights[right] * height);
                --right;
            }
        }
        // 返回结果
        return max;
    }
}