LeetCode中等:盛最多水的容器

盛最多水的容器(C#)

题目描述:给定 n 个非负整数 a,a2,…,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
说明:你不能倾斜容器,且 n 的值至少为 2
在这里插入图片描述

1.暴力法

思路:遍历数组,找到面积最大的区域并保存。

暴力法没什么好说的,直接上代码:

public static int MaxArea1(int[] height)
{
	int result = 0;
	for (int i = 0; i < height.Length; i++)
    {
	    for (int j = i+1; j < height.Length; j++)
        {
	        int h = height[i];
            h = height[j] > h ? h : height[j];
            int n = h * (j - i);
            result = n > result ? n : result;
		}
	}
    return result;
}

简单粗暴,显然时间复杂度为O(n2),空间复杂度为O(1)。

2.双指针法

思路:最基本的想法,面积的大小取决于两端中矮的一端的高度以及两端之间的距离。所以,我们从数组左右两端出发,将较矮一端处的指针向较高一端处移动,直到两个指针相遇。
这种思路简单的理解就是要想面积变大,就必须要将较矮端的指针移动,以为移动较高一端的指针只能使得面积变小。(当然这种想法比较粗糙,而且是在已经知道双指针法有效的基础上进行的推测)
ok,接下来进行严密的证明
要证明的命题是:双指针法的移动路径一定会经过构成最大面积的两个位置
首先我们假设有两个位置m和n构成最大面积(m<n,m和n的高度不确定,后面会分情况仔细讨论)。
由双指针法的移动方式可知,这个命题等价于m左侧点的高度都小于等于m的高度,n右侧点的高度也都小于等于n的高度。
我们假设在m左侧有一点的高度大于m的高度,那么就有以下三种可能性:
①m的高度小于n的高度,则有Areamn=(n-m) * m以及Areanp=(n-p) * max(p,n)
显然,n-p>n-m且max(p,n)>m,所以Areanp>Areamn。
②m的高度等于n的高度,则有Areamn=(n-m) * m以及Areanp=(n-p) * n
显然,n=m且max(p,n)>m,所以Areanp>Areamn。
③m的高度大于n的高度,则有Areamn=(n-m) * n以及Areanp=(n-p) * n
显然,n-p>n-m,所以Areanp>Areamn。
综上,不论哪种情况Areanp都大于Areamn,即np构成的面积会大于mn构成的面积,这与假设“m和n构成最大面积”不符。所以m的左侧不存在一点的高度大于m的高度,即m左侧点的高度都小于等于m的高度,得证。反之亦然。

ok,有了思路以及证明之后就是代码了。

public static int MaxArea2(int[] height)
{
	int result = 0;
    int i = 0;
    int j = height.Length - 1;
    while (i < j)
    {
    	int area = (j - i) * Math.Min(height[i], height[j]);
		result = area > result ? area : result;
		if (height[i] < height[j])
			i++;
        else
            j--;
   }
   return result;
}

这个方法就很棒了,时间复杂度是O(n),空间复杂度是O(1)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值