容器盛水问题

一、问题描述

给定一数组ary,元素两两组合,以min{ary[i],ary[j]}为高,以跨度(j-i)为宽可组成一个容器,求所有这样的容器的最大面积maxVolume。

二、算法分析

以数组ary为例:
int[] ary = {3,2,6,8,1,7};
如果从蛮力法的角度来看。
相当于从以上6个元素中选两个不考虑排序,是组合问题。
C(n,m) = C(6,2) = 15
不难想到,遍历15种组合的volume值,然后取其最大值,定能够求解。
但是我们真的需要求15中全部的情况吗?
从另一个角度看来
有ary[0]=3参与的情况5种,这些情况中最大的volume为v1
剩余组合中,有ary[1]=2参与的情况4种,这些情况中最大的volume为v2
剩余组合中,有ary[2]=6参与的情况3种,这些情况中最大的volume为v3
剩余组合中,有ary[3]=8参与的情况2种,这些情况中最大的volume为v4
剩余组合中,有ary[4]=1参与的情况1种这些情况中最大的volume为v5
不难发现全局最大的volume = max{v1,v2,v3,v4,v5}

但是此处的v1,v2,v3,v4,v5求取有的是比较繁琐,原因在于参与的边选取得不合理,
在换个角度
有min{ary[0],ary[5]}=ary[1]参与的情况,5种,这些情况中最大的volume为v1,且v1必为(5-0)*ary[0]
剩余组合情况种,有min{ary[1],ary[5]}=ary[1]参与的情况,4种,这些情况中最大的volume为v2,且v2必为(5-1)*ary[1]
剩余组合情况种,有min{ary[2],ary[5]}=ary[2]参与的情况,3种,这些情况中最大的volume为v3,且v3必为(5-2)*ary[2]
剩余组合情况种,有min{ary[3],ary[5]}=ary[5]参与的情况,2种,这些情况中最大的volume为v4,且v4必为(5-3)*ary[5]
剩余组合情况种,有min{ary[3],ary[4]}=ary[4]参与的情况,1种,这些情况中最大的volume为v5,且v5必为(4-3)*ary[4]
全局最大的volume=max{v1,v2,v3,v4,v5}

关键在于:如果参与的边是序列两端的最小边:min{ary[i],ary[j]},则在这些局部组合情况中,局部最大volume必定等于min(ary[i], ary[j])*(j-i)。

三、java实现

    public static int getMaxVolume(int[] ary,int low,int high){
        int i = low,j = high;//两指针,一前一后
        int maxVolume = 0;
        while(i<j){
            //容器的容量以ary[i]和ary[j]中较短边为高,跨度为宽
            maxVolume = Math.max(Math.min(ary[i], ary[j])*(j-i), maxVolume);
            if (ary[i]<ary[j]) {//移动的始终是短边
                i++;
            }else {
                j--;
            }
        }
        return maxVolume;
    }
时间: 2024-08-25 08:15:41

容器盛水问题的相关文章

leetcode 11盛水最多的容器

class Solution { public: int maxArea(vector<int>& height) { //双指针法:从最宽的容器开始计算,当更窄的容器盛水量要大于之前容器,那必须比之前容器高,因此可以移动两个指针,直到最窄time O(n),space O(1); int low=0; int high=height.size()-1; int volume=0; while(low<high){ int h=min(height[low],height[hig

LeetCode第11题 盛水最多的容器

/* 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) . 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0). 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水. 说明:你不能倾斜容器,且 n 的值至少为 2.*/ 思路: 类似于木桶效应. 每次移动较短的线,保持长线不动.(如果短线不动而长线动,容量减小(y没有增大反而x变小)) 记录最大值. 1 class Solution11 { 2 3 pu

盛水最多的容器

题目:给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水.说明:你不能倾斜容器,且 n 的值至少为 2.来源:https://leetcode-cn.com/problems/container-with-most-water/ 法一:双指针法 思路:由于是求最大的存水面积,易知影响存水面积S的只有两

leetcode 盛水最多的容器(双指针)

给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水. 说明:你不能倾斜容器,且 n 的值至少为 2. 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7].在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49. 示例: 输入: [1,8,6,2,5,4,8,3,7]输出: 49 来源

给jdk写注释系列之jdk1.6容器(1)-ArrayList

工作中经常听到别人讲“容器”,各种各样的容器,话说到底什么是容器,通俗的讲“容器就是用来装东西的器皿,比如:水桶就是用来盛水的,水桶就是一个容器.” ok,在我们写程序的时候常常要对大量的对象进行管理,比如查询,遍历,修改等.jdk为我们提供的容器位于java.util包,也是我们平时用的最多的包之一. 但是为什么不用数组(其实也不是不用,只是不直接用)呢,因为数组的长度需要提前确定,而且不能改变大小,用起来手脚受限嘛. 下面步入正题,首先我们想,一个对象管理容器需要哪些功能?增加,删除,修改,

投票系统——爬虫+容器克隆技术

序:昨天是所谓的单身狗节,作为一名不折不扣的程序员,高级程序员,怎么能有女票呢是吧,所以我苦逼的去了公司开发我的项目 大概到下午,我当天的开发到了尾声,仔细想想别人都去逛街约炮去了,我堂堂一名程序员弄啥雷,于是我想找点乐子,我找了实验室的好基友(单身狗程序员一只)准备商讨出去浪的想法,刚想发信息,一想最近工资没发,钱不够不能出去浪啊,寻思着找啥乐子,突然一个灵感划过脑海,要不做个校花评选系统找理工的校花吧,但是照片哪来呢,大一时天真的认为让他们自己交出照片,想想这么逗比的行为不现实了,那么只能做

给jdk写注释系列之jdk1.6容器(1):ArrayList源码解析

原文出自吞噬天地,链接整理自ImportNew 给jdk写注释系列之jdk1.6容器(2):LinkedList源码解析 给jdk写注释系列之jdk1.6容器(3):Iterator设计模式 给jdk写注释系列之jdk1.6容器(4)-HashMap源码解析 给jdk写注释系列之jdk1.6容器(5)-LinkedHashMap源码解析 给jdk写注释系列之jdk1.6容器(6)-HashSet源码解析&Map迭代器 给jdk写注释系列之jdk1.6容器(1):ArrayList源码解析 工作中

Javaweb里“容器“如何出现,应用在哪,未来发展趋势

容器是一个Java 所编写的程序,可当做一个工具,没有容器时必须自行编写程序以管理对象关系,现在容器都会自动做好. 有一说法:如果有一个类专门用来存放其它类的对象,这个类就叫做容器.另一说法:容器里存放的是对象的引用(或者说变量)而不是对象,对象还在容器外,容器内放的是对象的引用,类似于C语言的指针,也就是对象实例化后在堆内存中的地址,容器存放引用而不是存放对象本身也是容器设计巧妙的地方. 常用的容器有: WebSphere,WebLogic,Resin,Tomcat,Glassfish 容器的

水与人体

水与人体 1.水与人体健康的关系是什么? 答:水在人体的作用是:传送养分,促进液体循环,帮助消化,排泄废物,保持呼吸功能,润滑关节和调节体温.水不但起到体内物质输送与媒介作用,而且直接参与生物大分子结构,水与生物大分子共同完成了人体的物质代谢.能量代谢和信息代谢.水与衰老.寿命.免疫.代谢有直接的关系.水是生命之源,健康之本. 2. 水对人体健康有哪些帮助作用? 答:1)水能防治容颜早衰.脸部经常暴露在外,受风雨.冻晒刺激最多,水分损失也就最大,天长日久因缺水就脸早皱.眼早花.发早脱.如能及时补