题目要求:给一个数组,其中数组在下标i处的值为A[i],坐标(i,A[i])和坐标(i,0)构成一条垂直于坐标轴x的直线。现任取两条垂线和x轴组成四边形容器。问其中盛水量最大为多少?面试
这种实现很是原始,在这里就不赘述了,时间复杂度为O(n2),在数据量较大的时候,性能不好算法
减小循环的核心思路是省去没有必要的遍历,而且确保所需的答案必定能被遍历到
假设如今有一个容器,则容器的盛水量取决于容器的底和容器较短的那条高
则咱们能够从最大的底长入手,即当容器的底等于数组的长度时,则容器的盛水量为较短边的长乘底
可见 只有较短边会对盛水量形成影响,所以移动较短边的指针,并比较当前盛水量和当前最大盛水量。直至左右指针相遇。数组
主要的困惑在于如何移动双指针才能保证最大的盛水量被遍历到
假设有左指针left和右指针right,且left指向的值小于right的值,假如咱们将右指针左移,则右指针左移后的值和左指针指向的值相比有三种状况微信
综上所述,容器高度较大的一侧的移动只会形成容器盛水量减少
因此应当移动高度较小一侧的指针,并继续遍历,直至两指针相遇。性能
public int maxArea(int[] height) { int left = 0; int right = height.length-1; int max = 0; while(left<right){ max = Math.max(max, Math.min(height[left], height[right])*(right-left)); if(height[left]<height[right]){ left++; }else{ right--; } } return max; }
以前证实的只是在左指针不改变的状况下,左移右指针只会形成容器的容量减少。可是一旦紧接着左指针发生变化,就没法证实以该左指针为一侧高,右指针右侧的值生成的容器的容量比当前值小。
如下补充一个简单的反证法证实算法的合理性
当前的算法为:使用两个指针分别指向数组的头和尾。指向的值较小的那个指针移动,即左指针右移,右指针左移。当左右指针相遇时,指针
假设:该算法并无遍历到容量最大的状况
咱们令容量最大时的指针为p_left和p_right。根据题设,咱们能够假设遍历时左指针先到达p_left,可是当左指针为p_left时,右指针尚未通过p_right左指针就移动了
已知当左指针停留在p_left时,它只有在两种场景下会发生改变spa
所以该算法的遍历必定通过了最大的盛水量的状况指针
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注个人微信公众号!将会不按期的发放福利哦~code