您的位置:首页 > 大数据 > 人工智能

Container With Most Water容器盛水

2016-08-18 10:18 330 查看


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.
大概意思就是给你个数组,下标代表x坐标,数组元素代表相应的y坐标值。
从y坐标向x轴引垂线,求两条垂线,使得他们围成的容器装水最多。
双层for循环那种暴力解法肯定不会满足时间要求。所以尽量选择时间复杂度为O(n)的解法。
解题思路:首尾两个指针分别往中间移动,由于求装水最多,所以求area时,
只考虑对比的两条垂线中最短的那条就可以,每次都记录相应的area。
最后返回最大的area即可。首先想到了下面的第一个方法,但是这个方法还是超过了时间限制。如下:

public class Solution {
public int maxArea(int[] height) {
if (height.length<2) {
return 0;
}
int start = 0;
int end = height.length-1;
int area = 0;
while (start < end) {
int v  = Math.min(height[start], height[end])*(end-start);
area =Math.max(area,v);

if (height[start]<height[end]) {
start++;
}else {
end--;
}
}
return area;
}
}


然后,仔细考虑,发现,其实在移动的时候,以start为例,
当移动start时,它右边的值如果比start所在位置的元素小的时候,可以不用计算了,
因为它不会在比start位置的元素求的area大。
end方向同理。继续优化上面的方法得到下面的代码:
public class Solution {
public int maxArea(int[] height) {
if (height.length<2) {
return 0;
}
int start = 0;
int end = height.length-1;
int area = 0;
while (start < end) {
int v = Math.min(height[start], height[end])*(end-start);
area =Math.max(area,v);

if (height[start]<height[end]) {
int k = start;
while (k < end && height[k]<=height[start]) {//只要start右边的元素比start所在位置的元素小
k++; //就可以不用在算面积,因为不会比start所在位置的元素求出的面积大
}
start = k;
}else {
int k = end;
while (k > start && height[k]<=height[end]) {//只要end左边的元素比end所在位置的元素小
k--; //就可以不用在算面积,因为不会比end所在位置的元素求出的面积大
}
end=k;
}
}
return area;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: