Container With Most Water

原题:

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.

题目理解:

题目的意思就是给定一个数组分布在XY坐标系中,然后求解哪两个元素和X轴组成一个水桶之后能够装的水最多。例如有a[i]和a[j]两个元素中(i<j)比较小的是a[i],则找出a[i]*(j-i)最大的值。

首先想到的解法就是列举所有的可能情况,然后进行大小的比较。代码如下:

public class Solution {
    public int maxArea(int[] height) {
        int maxarea = 0;
        for (int i = 0; i < height.length; i++)
            for (int j = i + 1; j < height.length; j++)
                maxarea = Math.max(maxarea, Math.min(height[i], height[j]) * (j - i));
        return maxarea;
    }
这样做的话,算法的时间复杂度是 O ( n2 )。这个算法的效率是不高的,做了太多的无用的比较。

对上面的算法进行了优化,减少了部分无用的比较,代码如下:

class Solution {
    public int maxArea(int[] height) {
        int laragArea = 0;
        for (int i = 0; i < height.length-1; i++){
            if (height[i] == 0){
                continue;
            }
            for (int j = i+1+laragArea/height[i]; j < height.length; j++){
                int min = Math.min(height[i], height[j]);
                int area = min * (j-i);
                if (area > laragArea){
                    laragArea = area;
                }
            }
        }
        return laragArea;
    }
}

该算法的主要想法是跳过开始就不可能成为最大面积的元素,因此对比第一个解法,在第二重循环中,j并不是从i+1开始,而是从可能成为最大面积的i+1+laragArea/height[i]开始,从而减少了部分比较。然而该算法在极坏的情况下,时间复杂度仍为O(n2),和第一个解法没有差别。

由此有了第三种解法,解法的思想是离得远的两个元素最有可能成为最大面积。设置两个指针,一个从0开始,一个从最后开始,每次均比较这两个元素组成的面积和保存的最大面积,然后将较小的元素的指针向中间移动,知道两个指针重合的时候,就可以得到最大的面积了。

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值