11. Container With Most Water
题目:
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.
Note: You may not slant the container.
链接:http://leetcode.com/problems/container-with-most-water/
题解:Two Pointers, 每次移动至较小的一个pointer。Time Complexity - O(n), Space Complexity - O(1)
public class Solution { public int maxArea(List<Integer> height) { if(height == null || height.size() < 2) return 0; int max = 0, left = 0, right = height.size() - 1; while(left < right){ int curArea = Math.min(height.get(left), height.get(right)) * (right - left); max = Math.max(max, curArea); if(height.get(left) < height.get(right)) left++; else right--; } return max; } }
二刷:
经典的Two Pointers方法,前后夹逼一下就可以得到结果了。二刷时发现signature变了。
Java:
public class Solution { public int maxArea(int[] height) { if (height == null || height.length == 0) { return 0; } int maxVolumn = 0; int lo = 0, hi = height.length - 1; while (lo < hi) { int curVolumn = Math.min(height[lo], height[hi]) * (hi - lo); maxVolumn = Math.max(maxVolumn, curVolumn); if (height[lo] < height[hi]) { lo++; } else { hi--; } } return maxVolumn; } }
Python:
class Solution(object): def maxArea(self, height): """ :type height: List[int] :rtype: int """ lo = 0 hi = len(height) - 1 maxVolumn = 0 while lo < hi: curVolumn = min(height[lo], height[hi]) * (hi - lo) maxVolumn = max(maxVolumn, curVolumn) if height[lo] < height[hi]: lo += 1 else: hi -= 1 return maxVolumn
题外话:
Python真的短,希望深入学习以后能更短。
三刷:
这种小的code snippet一定要熟练,说不定可以用到哪一个大段的程序里。 像这道题的方法,就可以在"Trapping Rain Water"里面使用。很多算法,思想都是想通的,要多学多练,融会贯通。
这里我们的面积等于左边和右边较小的bar * (hi - lo),每次都要尝试更新一下max。 之后,移动两根bar中较短的一根。
注意这里的高度是两根bar中较小的一根,长度是 hi - lo。可以想象成两根细线中间夹的区域,并不是hi - lo + 1。
Java:
Time Complexity - O(n), Space Complexity - O(1)
public class Solution { public int maxArea(int[] height) { if (height == null || height.length < 2) return 0; int lo = 0, hi = height.length - 1; int max = 0; while (lo < hi) { max = Math.max(Math.min(height[lo], height[hi]) * (hi - lo), max); if (height[lo] < height[hi]) lo++; else hi--; } return max; } }
Reference:
https://leetcode.com/discuss/1074/anyone-who-has-a-o-n-algorithm