11.Container With Most Water---两指针
题目链接:https://leetcode.com/problems/container-with-most-water/description/
题目大意:给出一串数组(a1, a2, a3, ...an),表示坐标(i, ai),同样表示一条直线是从(i, 0)到(i, ai),从中选出两条直线,计算其容器能蓄水多少,并找出最多的蓄水量。(容器不能倾斜,就是两条直线可以是不同高度,但是蓄水量要按照低高度的那条直线来计算),例子如下:
法一:暴力,对于一条直线,分别遍历左边和右边直线,计算其蓄水量,取最大者。可惜超时了。代码如下:
1 public int maxArea(int[] height) { 2 int res = 0; 3 for(int i = 0; i < height.length; i++) { 4 //计算左边直线 5 for(int j = height.length - 1; j > i; j--) { 6 if(height[j] >= height[i]) { 7 res = Math.max(res, (j - i) * height[i]); 8 break; 9 } 10 } 11 //计算右边直线 12 for(int j = 0; j < i; j++) { 13 if(height[j] >= height[i]) { 14 res = Math.max(res, (i - j) * height[i]); 15 break; 16 } 17 } 18 } 19 return res; 20 }
法二:两指针移动,与42题的两指针移动类似但略有区别,左指针与右指针相比较,记录较大者,若左指针较小,则从左往右移动,若右指针较小,则从右往左移动,如果当前值比较大者大,则计算:(较大者下标-当前值下标)*当前值高度,计算得到最后的结果。代码如下(耗时8ms):
1 public int maxArea(int[] height) { 2 int res = 0, left = 0, right = height.length - 1; 3 while(left < right) { 4 //如果左指针<=右指针 5 if(height[left] <= height[right]) { 6 while(left < right && height[left] <= height[right]) { 7 res = Math.max(res, (right - left) * height[left++]); 8 } 9 } 10 //如果左指针>右指针 11 else { 12 while(left < right && height[left] > height[right]) { 13 res = Math.max(res, (right - left) * height[right--]); 14 } 15 } 16 } 17 return res; 18 }