11. 盛最多水的容器

给定 n 个非负整数 a1,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

在这里插入图片描述
垂直的两条线段将会与坐标轴构成一个矩形区域,较短线段的长度将会作为矩形区域的宽度,两线间距将会作为矩形区域的长度,而我们必须最大化该矩形区域的面积。这里笔者使用了两种方法-暴力破解法/双指针法
暴力破解法:
遍历两遍数组,第一遍i是容器左端,第二遍从i后面开始的j确定容器右端,容量就是min(height[i],height[j])*(i-j),设定一个max每次与其进行比较存放最大容量即可,很好实现,但这种办法时间复杂度太高O(n2):
参考代码:

int maxArea(int* height, int heightSize) {
    int tall  = 0,len = 0,max = 0;
    for(int i =0;i<heightSize;i++){
        for(int j =i+1;j<heightSize;j++){
            tall = height[i]<height[j]?height[i]:height[j];
            len = j-i;
            int capacity = tall*len;
            max = max>capacity?max:capacity;
        }
    }
    return max;
}

双指针法:
这个方法使用两个指针,分别位于头尾,两端中最小(短)的那个,我们可以视之为拖后腿的,为了不拖后腿获以得最大面积,它将要向内侧移动去寻找变大的可能,即使向内侧靠拢会减小长度,但若能变得更大(高),我们将能够弥补这个损失,每移动一步,进行一次判断,直至两个指针相遇;在这个过程中,和之前方法一样,用max记录下最大容量值,此时因为只遍历了一边数组,所以时间复杂度大幅降低为O(n):
参考代码:

int maxArea(int* height, int heightSize) {
    int left = 0,right = heightSize-1,max =0,capacity,tall;
    while(left<right){
        tall = height[left]<height[right]? height[left]:height[right];
        capacity = tall*(right-left);
        max = max>capacity?max:capacity;
        if(tall==height[left]){
            left++;
        }else{
            right--;
        }
    }
    return max;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值