LeetCode---Container With Most Water(11)

Description: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
问题:对于非负整数数组:[a1,a2,a3,…,an],点(i,0)(i,ai)组成线段i,点(j,0)(j,aj)组成线段j,这两条线段与x轴组成一个容器,求解使得容器可容纳水最多时的截面面积Area=|i-j|*min(ai,aj)。

以下描述中假定i<j
解法1(暴力解法):
拿到题目首先会想到使用暴力解法,即算出所有线段之间可能组成的面积,再找到其中的最大面积。
Python:

class  Solution(object):
	def maxArea(self, height):
		length = len(height)
		MaxArea = 0
		for i in range(length):
			j = i+1
			while(j<length):
				MaxArea = max(MaxArea, (j - i)*min(height[i], height[j]))
				j = j+1 
		return MaxArea

当提交代码后会提示超时。显而易见当数组height很大时,使用该方法需要计算出所有结果,算法时间复杂度为:O(n^2)

思考一下:如何减少计算次数,使算法复杂度为O(n)?即能否只遍历一次数组就能找到最大值?对于面积Area=(j-i)*min(ai,aj),假设min(ai,aj)=ai时,当(j-i)越大Area值才会越大。即应选择离ai最远的大于ai的元素。

解法2
参考上述思路,设置两个指针i,j指向数组最左端与最右端,当最左端值小于最右端时,保存面积Area = (j-i)*min(height[i],height[j]),接着指针i向右移动,继续比较。当最右端小于最左端时,保存面积,接着指针j向左移动,继续比较。
Python:

class Solution(object):
    def maxArea(self, height):
        i, j = 0, len(height) - 1
        MaxArea = 0
        while (i < j):
        	MaxArea = max(MaxArea, (j - i)*min(height[i], height[j]))
        	if height[i] < height[j]:
        		i=i+1
        	else:
        		j=j-1
        return MaxArea

原文地址:https://www.cnblogs.com/lliuye/p/7803012.html