这是悦乐书的第350次更新,第375篇原创
java
今天介绍的是LeetCode算法题中Medium级别的第5题(顺位题号是11)。给定n个非负整数a1,a2,…,an,其中每一个表示坐标(i,ai)处的点。绘制n条垂直线,使得线i的两个端点位于(i,ai)和(i,0)。找到两条线,它们与x轴一块儿造成一个容器,这样容器就含有最多的水。算法
注意:您可能不会倾斜容器,n至少为2。
上面的垂直线由数组[1,8,6,2,5,4,8,3,7]表示。 在这种状况下,容器可容纳的最大水面积(蓝色部分)为49。例如:数组
输入:[1,8,6,2,5,4,8,3,7]
输出:49
数据结构
暴力解法,使用两层循环,装水容器的宽为两元素索引之差,高为两元素中的较小值,利用宽乘以高,计算容器的面积,取其中较大值返回。3d
此解法的时间复杂度是O(N^2)
,空间复杂度为O(1)
。指针
public int maxArea(int[] height) { int result = 0, n = height.length; for (int i=0; i<n; i++) { for (int j=i+1; j<n; j++) { int w = j-i; int h = Math.min(height[i], height[j]); result = Math.max(result, w*h); } } return result; }
双指针。定义两个变量,一个从数组的头部开始,记为start
,另一个从尾部开始,记为end
,依旧按照第一种解法中那样计算面积和取最大值,而后来判断哪一个指针该往哪一个方向移动。code
若是start
位置的元素值小于end
位置的元素值,那么start
位置须要找到一个更大的值,才有可能比当前的面积大,因此start
须要自增1,向end
方向移动,反之就是end
位置须要向start
位置方向移动,来找到一个更大的元素值。blog
此解法的时间复杂度是O(N)
,空间复杂度为O(1)
。索引
public int maxArea2(int[] height) { int start = 0, end = height.length-1; int result = 0; while (start < end) { int w = end - start; int h = Math.min(height[end], height[start]); result = Math.max(result, w*h); if (height[start] < height[end]) { start++; } else { end--; } } return result; }
若是你以为第二种解法中,没有讨论两边的元素相等时的状况,那咱也能够再多加一个判断。class
public int maxArea3(int[] height) { int start = 0, end = height.length-1; int result = 0; while (start < end) { int w = end - start; int h = Math.min(height[end], height[start]); result = Math.max(result, w*h); if (height[start] < height[end]) { start++; } else if(height[start] > height[end]) { end--; } else { start++; end--; } } return result; }
算法专题目前已连续日更超过六个月,算法题文章218+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是所有内容,若是你们有什么好的解法思路、建议或者其余问题,能够下方留言交流,点赞、留言、转发就是对我最大的回报和支持!