Leetcode011. Container With Most Water

来源:互联网 发布:路由器选择算法 要求 编辑:程序博客网 时间:2024/06/05 20:54
题目:

Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.

题目大意:

给出n个竖直的柱子,每个珠子有高度a,求哪两个柱子中间可以装的水最多。

思路:

非常有趣的一题。

暴力算法O(n²)两两枚举,TLE。

优化的思路:

在我们暴搜的时候,枚举了许多不够优的情况(比如两根柱子离的很近而且很矮)。想要优化就必须把这些冗余的比较除去。

这时候我们研究一下“装水”的计算方法:min(a[i],a[j])*dis[i][j]。

对于这种有两个变量的问题,最好控制其中一个变量相同或者有序。高度自然不可能有序,所以想到用两个指针left和right,从两端向中间逼近,使距离递减。

那么怎么样移动left和right,使算法既不做多余枚举,又能保证正确性呢?

正解是,若a[left]<a[right],则把left向右移动,否则把right向左移动。在移动的同时不断更新水量的最大值。

为什么这样做是对的?

观察到,水量只与两根柱子的距离和这两根柱子高度的较小值决定。若a[left]<a[right]时,把right往左移动,min(a[left],a[right])显然不可能增大,而dis[i][j]又在减小,不可能取到更优的值。所以只能移动left。

代码:

python:

class Solution(object):    def maxArea(self, height):        """        :type height: List[int]        :rtype: int        """        ans = i = 0        j = len(height) - 1        while (i < j):            ans = max(ans, (j - i) * min(height[i], height[j])) # 更新最大值            if height[i] < height[j]: # 哪边矮就移哪边                i += 1            else:                j -= 1        return ans

原创粉丝点击