[LeetCode11题盛最多水的容器] | 刷题打卡

吐槽君 分类:javascript

前言:

之前学习的时候有学过双指针算法,但是平时用的不多,这次拿一道力扣的中等题来练练手,巩固一下自己学过的知识。

本文正在参与掘金团队号上线活动,点击 查看大厂春招职位

一.题目描述:

给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

说明:你不能倾斜容器。

示例1:

question_11.jpg

输入:[1,8,6,2,5,4,8,3,7]

输出:49

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

示例2

输入:height = [1,1]

输出:1

示例3

输入:height = [4,3,2,1,4]

输出:16

来源:力扣(LeetCode)leetcode-cn.com/problems/co…

二.思路分析:

1.题目分析:给出一组非负整数数组,每个元素按下标顺序排入坐标轴中画垂直线,每个元素坐标轴中的垂直线高度为它的元素值,我们需要找出两线之间所能构成的最大的矩形容器

2.要点剖析:题目最终是让我们求得两线之间构成的能装纳最多水的容器,可以理解成求两线之间的矩形面积,这个矩形的高要取两边中较小的一边,这是宽,矩形的长度则是取两边之间的距离,这是长。现在以长宽为要点驱动,使两边的距离尽量长,两边的高度差值尽量大

3.解题思想:既然矩形面积需要同时考虑坐标轴左右两边的长度,这道题目可以使用双指针的算法思想进行解决,首先,设置一个左指针left让它指向数组最左端,一个右指针right让它指向数组最右端,总体思路是让左右指针逐渐向中间靠拢,给左右指针设置递进规则:当一边垂直线的高度值大于另一边垂直线时,高度值低的那一侧的指针向中间推进(两边一样打时,默认左指针推进),这样是为了留住较大的一条边垂直线,尽可能构成更大的面积值。左右指针推进前设置一个记录值res,移动过程中记录最大的面积值,如果出现更大的面积则进行替换,在双指针跑完一遍停止后就能取得最大的面积了

4.复杂度时间复杂度 O(N):双指针遍历一次底边宽度 N 。空间复杂度 O(1):指针使用常数额外空间。

三.代码

var maxArea = (width) => {
  let i = 0; 
  let j = width.length - 1; //
  let res = 0; // 设置记录值来记录最大面积
  while(i < j) { // j不再大于i时,终止循环
    res = width[i] < width[j] ?  // 用三元运算符来进行条件判断,推进指针
      Math.max(res,(j - i) * width[i++]):
      Math.max(res,(j - i) * width[j--]);
  }
  return res;
}
 

四.总结

这是一道很经典的面试题,它的最有解之一就是使用双指针算法进行解决,通过左右指针的遍历来求得最大值。通过这道题,我对于双指针算法的理解更加的深入了,这也算是对自己前段时间算法学习的一次知识巩固,让自己有所收获,希望这篇文章也能够对你有所帮助,让你能够理解一些双指针算法,最后,如果觉得这篇文章还不错的话,希望可以帮忙点个赞哦,万分感谢。

image.png

回复

我来回复
  • 暂无回复内容