Leetcode-11:Container With Most Water

来源:互联网 发布:淘宝电影票能退吗 编辑:程序博客网 时间:2024/06/06 09:27

Question:

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 and n is at least 2.

给定一个数组,包含n个非负整数a1,a2,a3……,每个非负整数代表一个坐标(i,ai),以这个坐标为端点向x轴作垂线,那么这条线的两个端点就是(i,ai)和(i,0)。找到两条线,连同x轴形成一个容器,使容器容纳最多的水。
Note:你不能倾斜容器 && n至少是2

Answer:
题目就是要找到容器最大盛水量。
第一种方法:两层循环,一直找一直找……(提交超时)

public int maxArea(int[] height) {        int len = height.length;        int x,y;        int maxWater = 0;        int tmpWater = 0;        for(x=0;x<len;x++){            for(y=x;y<len;y++){                tmpWater = Math.min(height[x],height[y])*(y-x);                maxWater = Math.max(maxWater,tmpWater);            }        }        return maxWater;    }

第二种方法:
我们可以设置两个指针left和right,分别从数组左右两端向中间开始查找,当left>=right时,查找结束。
当left和right指针指向两个不同的边时,我们计算他的容器最大盛水量,然后移动指针,那么如何确定是移动left指针还是right指针?由于指针是向中间移动的,所以不管是left指针移动还是right指针移动,容器的底都会减小1,那么为了使得容器的盛水量增加,我们需要不断地增加高度,这时我们需要判断一下当前我们的容器左右边的长度,只有淘汰较短的那条边,才有可能增加当前边的高度(虽然也有可能减小,但是没关系,减小的话我们已经把最大值保存下来了),使得容器的盛水量进一步增大。
因此当height[left] < height[right]时,明显left指针指示的边长度要小于right指针指示的边,因此left++。反之right++;

public int maxArea(int[] height){        int left = 0;        int right = height.length-1;        int maxWater = 0;        int tmp_water = 0;        while(left<right){            tmp_water = Math.min(height[left],height[right])*(right-left);            if(height[left]<height[right]){                left++;            }else{                right--;            }            maxWater = Math.max(maxWater,tmp_water);        }        return maxWater;    }

(而使用height[left+1]和height[right-1]判断哪个指针需要移动的想法:当指针的下一条边更大的时候当然要走向下一条更大的边……这种思路是不正确的,因为这样有可能会错过最大的那条边,会使你丢失正确答案

//错误代码public int maxArea(int[] height){        int left = 0;        int right = height.length-1;        int maxWater = 0;        int tmp_water = 0;        while(left<right){            tmp_water = Math.min(height[left],height[right])*(right-left);            if(height[left+1]>height[right-1]){                left++;            }else{                right--;            }            maxWater = Math.max(maxWater,tmp_water);        }        return maxWater;    }Input: [1,2,4,3]Output: 3Expected: 4

最大盛水量是4,但是输出却是3,为什么?因为当left=0,right=3时,他们的下一条边4>2,因此,right–,这一移动不要紧,直接就错过了最大盛水量容器的一条边)。

原创粉丝点击