首页 > 其他分享 >装最多水的容器 - 题解

装最多水的容器 - 题解

时间:2023-05-08 13:11:57浏览次数:55  
标签:容器 int 题解 height a0 maxVolumn 最多水 ai

1. 问题描述

  原题的地址见:Container With Most Water - LeetCode. 此问题等价于如下问题:

    给定所有元素非负的数组[a0, a1, ..., an-1], 计算(j - i)|aj - ai|(其中j > i)的最小值。

 

2. 暴力解法

  有了问题的描述,很容易写出暴力求解的算法:

int maxArea(vector<int>& height) {
    int maxVolumn = 0;
    for (int i = 0; i < height.size(); ++i) {
        for (int j = i + 1; j < height.size(); ++j) {
            int currentVolumn = (j - i) * min(height[j], height[i]);
            if (currentVolumn > maxVolumn) {
                maxVolumn = currentVolumn;
            }
        }
    }
    return maxVolumn;
}

  即:计算所有的(j - i)|aj - ai|, 找出最大的值,时间复杂度为O(n2).

 

3. 更优的解法

  对于这个问题,不需要遍历每个(ai, aj)对。解法如下:

  假设输入为[a0, a1, ..., an-1],

    (a.) 设置两个指针i, j分别指向数组两端的元素, 即i = 0, j = n - 1. 置初始时的最大体积maxV = 0.

    (b.) 如果i < j, 计算当前的容器体积:v = (j - i) *  min(aj, ai), 置maxV = max(maxV, v); 否则(即i≥j时)返回maxV.

    (c.) 如果ai < aj, 则i = i + 1, 否则j = j - 1, 跳转到(b.).

  这种解法更为有效,因为仅遍历了一次数组,其时间复杂度为O(n). 现在的关键问题是,它为什么是正确的?

  考虑第一次进入循环的情况,即i = 0, j = n - 1, 不妨设a0 < an-1. 这样,在第一次循环后,i = 0 + 1 = 1. 也就是说,我们淘汰了情况(a0, a1), (a0, a2), ..., (a0, an-2). 这些对为什么可以淘汰呢?

  原因在于,对于任意的对(a0, ak)(k = 1, 2, ..., n-2):

    如果ak ≤ a0, 那么(a0, ak)构成容器的体积为(k - 0) * ak, 显然小于(a0, an-1)构成容器的体积(n - 1 - 0) * a0.

    如果ak > a0, 那么(a0, ak)构成容器的体积为(k - 0) * a0, 这仍然小于(a0, an-1)构成容器的体积.

  因此,对于a0 < an-1的情况, (a0, an-1)构成的容器是有a0参与构成的容器中体积最大的那一个。因此,每次迭代时,我们只需要更新ai, aj中较小的那个所对应的下标即可。从这个问题中可以看出一种短板效应。

  具体的C++实现如下:

int maxArea(vector<int>& height) {
    int i = 0, j = height.size() - 1;
    int maxVolumn = 0; 
        
    while (i < j) {
        if (height[i] < height[j]) {
            maxVolumn = max(maxVolumn, height[i] * (j - i));
            ++i;
        }
        else {
            maxVolumn = max(maxVolumn, height[j] * (j - i));
            --j;
        }
    }

    return maxVolumn;
}

 

标签:容器,int,题解,height,a0,maxVolumn,最多水,ai
From: https://www.cnblogs.com/overxus/p/17381416.html

相关文章

  • Windows 安装 pycrypto 常见问题解决
    关于python使用Crypto.Cipher模块,ImportError:Nomodulenamed'Crypto' 常见问题解决1. 需要安装:MicrosoftVisualC++14.0error:MicrosoftVisualC++14.0isrequired.Getitwith"MicrosoftVisualC++BuildTools":http://landinghub.visualstudio.co......
  • Springboot 自定义Web容器
    Springboot自定义Web容器如果你的项目并发量比较高,想要修改最大线程数、最大连接数等配置信息,可以通过自定义Web容器的方式,代码如下所示。@SpringBootApplication(proxyBeanMethods=false)publicclassAppimplementsWebServerFactoryCustomizer<ConfigurableServletWebSer......
  • CF1794D 题解
    一、题目描述:一个正整数$m$可以被唯一分解成$p_1^{e_1}\timesp_2^{e_2}\times...\timesp_k^{e_k}$的形式,其中$p_1,p_2,...,p_k$为互不相同的质数,$e_1,e_2,...,e_k$为正整数。定义一个可重集$f(m)$为$\{p_1,e_1,p_2,e_2,...,p_k,e_k\}$。现在给定正整数$......
  • 51nod 1365 Fib(N) mod Fib(K)-题解
    51nod1365Fib(N)modFib(K)个人评价:考一些奇奇怪怪的知识点呢算法矩阵快速幂、斐波那契公式题面求\(F_n\%F_k\)的值,\(1\leqn,k\leq1e18\)问题分析我一开始居然想着直接矩阵快速幂求出两个值算,我也是真的牛……我们要知道这些斐波那契公式(考的真怪)\[F_{-n}=(-1)^{n......
  • 2023ccpc湖北省赛/2023 Hubei Provincial Collegiate Programming Contest个人题解
    2023HubeiProvincialCollegiateProgrammingContestAPrimeMagicWalkAlonehasasequence\(a_1,a_2,...,a_n\),andhecanuseamagiconit:Chooseanoddprimenumber\(p\)andaninterval\([l,r]⊆[1,n]\)satisfying\(r−l+1=p\),andthenadd......
  • MultiDex使用方法及由此导致的crash、ANR问题解决方案
    Android开发的朋友,如果是在开发一款中大型应用时,都会碰到这么一个问题,就是dex分拆问题,google给出的解决方案MultiDex。现象:有些APP本身功能比较多,再加上一些其它三方的SDK,慢慢的发现dex越来越大,直到有一天编译出现如下错误:Error:Thenumberofmethodreferencesina.dexfile......
  • 十二代酷睿处理器N100 N200 N305 等安装ESXI紫屏问题解决办法
    12代大小核紫屏报错解决方案四部曲1、安装界面倒计时结束之前,按SHIFT+O,在原有命令后面加空格后输入以下代码cpuUniformityHardCheckPanic=FALSE2、安装完ESXI之后会重启,在重启界面倒计时结束前,再操作一次,按住SHIFT+O,输入cpuUniformityHardCheckPanic=FALSE3、进入ESXI把SSH功能......
  • 无根容器内部结构浅析
    随着云计算的发展,容器变得越来越流行,同时也产生了实现容器的新方案,其中之一就是无根容器。本文介绍了无根容器的内部结构,并分析了无根容器网络组件中的漏洞。随着云计算的发展,容器变得越来越流行,同时也产生了实现容器的新方案,其中之一就是无根容器。无根容器是不需要root即可创建得......
  • 力扣《环形链表Ⅱ》超详细题解
    作为经典题目的《环形链表Ⅱ》,我认为这题还是有专门出一期博客的分量的,大家也可以自己事先按照自己的理解写一写,然后再来看题解,毕竟自己悟出来的东西是比吸收别人的来的更深刻。一、题目给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。......
  • CF1829B 题解
    题目思路先定义变量\(t,ans\)。循环从\(0\)到\(n-1\),对于第\(i\)个数,如果为\(0\),\(t=t+1\),否则将\(t\)清零。每次循环\(ans=\max(ans,t)\)表示最多有多少个连续的\(0\)。最后输出\(ans\)即可。核心代码点击查看代码voidsolve(){intn=read(),a[1005],a......