今天给大家分享的是一道LeetCode中等难度的题,难度不大,但是解法蛮有意思。我们一起来看题目:

Link

Container With Most Water

Difficulty

Medium

题意

给定n个非负整数,表示水库当中隔板的高度每两块隔板之间的距离为1,当下要从n个隔板当中选出两个,在其中注水,并且要使得容纳的水尽量多。请问最多能容纳多少水?可以忽略隔板的宽度,将水库看成是正规的长方体。

样例:

Input: [1,8,6,2,5,4,8,3,7]
Output: 49

题解:

由于水库可以看成是正规的长方体,所以水库的体积可以简化为横截面积。也就是说我们要选择两个隔板,使得隔板之间围成的矩形面积最大。

首先思考暴力求解,我们只需要枚举矩形的两边,两边有了之后,矩形的长,也就是两边之间的距离,矩形的宽就是两边的较小值,所以复杂度是\(O(n^2)\)。

这样写的代码也很简单,只有几行:

for i in range(n):
for j in range(i+1, n):
ret = max(ret, (j-i) * min(a[i], a[j]))
return ret

我们来思考怎么优化,显然大部分情况下\(O(n^2)\)的算法往往都不是最优解。考虑一个很简单的问题,为什么取最左边和最右边的隔板不行呢?这样不是矩形的长最长么?

不行的原因很简单,因为矩形的长最长的时候,但是矩形的宽不一定很宽。有可能这样的宽很短,就像上面图中展示的一样。如果这时候的结果不是最佳值,那么最佳答案的长一定小于n。如果我们用i和j指代最优解的左右两边的下标,那么显然有1 <= i < j <= n。

也就是说i, j 的位置应该在1, n的内部。我们可以想象一开始的时候i指向1,j指向n,然后逐渐移动到了最优解的位置。我们应该移动i和j,但是每次应该怎么移动呢?究竟是移动i还是移动j呢?

其实稍微想一下就能想到答案,应该移动i和j两个当中隔板比较短的那个。假设i的隔板长度小于j,即使移动i,即使碰到了更长的隔板,面积也不会变大,因为j的长度并没有变,它依旧是短板。所以我们只有移动其中较短的那个,才有让矩形面积变大的可能。

如果i和j的长度一样怎么办?答案是随便移动哪个都一样,有些同学可能还有顾虑。我们不妨使用一下我们之前介绍贪心算法的时候提到的均等假设法。有忘记的同学可以点击下方的链接回顾一下:

贪心算法与均等假设法

我们来举个例子,假设水库隔板的情况是:

5 10 X .. X 4 5

我们一开始的时候i指向左边的5,j指向右边的5,这时候i和j相等。如果移动左边的i,到10,面积并没有变大。接下来会一直移动右边的j,直到j遇到大于10的为止。并不会出现影响正确结果的情况。如果移动右边的j呢?其实也是一样的,因为如果j没有遇到大于5的元素,无论左边指向什么地方,面积都不会增大。当j遇到5以上的数的时候,必然会移动左边的i,一样可能增大面积。

5 10 X .. X 11 5

我们再看这个例子,如果10和11围成的结果是正确答案,那么不论先移动i还是先移动j都是一样的。本质上来说,如果矩形面积要增大,必须要i和j同时指向比当前更大的元素才行,所以先移动哪个并不会影响结果。

这样一来,写代码就方便了,我们可以人为规定如果出现相等,就移动i。写出来代码如下:

i, j = 0, n-1
ret = 0
while i < j:
ret = max(ret, (j - i) * min(a[i], a[j]))
if a[i] <= a[j]:
i += 1
else:
j -= 1
return ret

这道题既可以认为是贪心算法,也可以认为是两指针维护区间的问题。不论怎么样解释,写出来的代码是一样的,我个人觉得还是很巧妙的,很适合初学者练手,并且难度也不是很大。希望大家都能领会。

今天的文章就到这里,如果觉得有所收获,请顺手点个关注吧,你们的支持是我最大的动力。

LeetCode 11 水池蓄水问题的更多相关文章

  1. leetcode 最大水池

    leetcode 11题 水池最大容积 题目描述 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 ( ...

  2. LeetCode 11. Container With Most Water (装最多水的容器)

    Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai).  ...

  3. [LeetCode] 11. Container With Most Water 装最多水的容器

    Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). ...

  4. Java实现 LeetCode 11 盛最多水的容器

    11. 盛最多水的容器 给定 n 个非负整数 a1,a2,-,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) ...

  5. 如何装最多的水? — leetcode 11. Container With Most Water

    炎炎夏日,还是呆在空调房里切切题吧. Container With Most Water,题意其实有点噱头,简化下就是,给一个数组,恩,就叫 height 吧,从中任选两项 i 和 j(i <= ...

  6. LeetCode 11

    Container With Most Water Given n non-negative integers a1, a2, ..., an, where each represents a poi ...

  7. LeetCode——11. Container With Most Water

    一.题目链接:https://leetcode.com/problems/container-with-most-water/ 二.题目大意: 给定n个非负整数a1,a2....an:其中每一个整数对 ...

  8. LeetCode 11 Container With Most Water(分支​判断问题)

    题目链接 https://leetcode.com/problems/container-with-most-water/?tab=Description   Problem: 已知n条垂直于x轴的线 ...

  9. LeetCode(11)题解: Container With Most Water

    https://leetcode.com/problems/container-with-most-water/ 题目: Given n non-negative integers a1, a2, . ...

随机推荐

  1. 创意app1

      app名称: 与我相似的人 app目的: 旨在通过云匹配,搜索到与自己类似爱好或者性格的人用户相似的内容:衣服品牌鞋子手机笔记本键盘鼠标相机刮胡刀自行车工作  说明: 现有的格局 百度贴吧是面向多 ...

  2. FCKeditor使用

    fckeditor - (1)资料介绍与安装 fckeditor介绍  FCKeditor是一个专门使用在网页上属于开放源代码的所见即所得文字编辑器.  1.fckeditor官网:http://ww ...

  3. Linux(Centos)安装node及anyproxy

    一.安装node //下载 wget https://nodejs.org/dist/v10.9.0/node-v10.9.0-linux-x64.tar.xz //解压 tar xf node-v1 ...

  4. 并查集的超市问题---溜TM的

    三个月前我就错了,现在又错了,我就是个傻****** 服了,看图哇 打扰了... #include<cstdio> #include<iostream> #include< ...

  5. centos批量创建用户并发送邮件,(修订版)

    # cat user_create.sh echo -n "创建用户输入C,删除用户输入D!" read name function monitor() { if [ " ...

  6. Spring Boot 配置文件中使用变量、使用随机数

    参数引用 在application.properties中的各个参数之间可以直接通过是使用placeHolder的方式进行引用,如: book.author=Clark book.name=C++ b ...

  7. ECMAScript新语法、特性总结

    前言 从2015年的ES6开始,JavaScript的语言标准每年都在更新,其中尤其以ES6的力度之大,到现在ES10已经发布,这里总结一下新语法. 参考:阮一峰 ECMAScript 6 教程 .E ...

  8. 电脑端TIM登录时记住密码

    为什么每次登录TIM时点了记住密码,下次再登录时还是记不住呢? 不是扫码就是还得输出密码,为这事愁了好多次, 最近终于发现如何记住密码了... 进入登录界面以后,点击左下角这个小图标>> ...

  9. 通俗易懂理清mybatis中SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之间的关系

    我潇洒的灰大狼又回来啦.今天送大家的一句话是: 保持耐心,永远年轻,永远热泪盈眶. 前言 先容我哭一会儿,呜呜呜~昨晚写了一半的文章,还没保存就盖上盖子准备回家,拔下电源准备把电脑塞进书包带回家完成时 ...

  10. Win10该文件没有与之关联的应用来执行该操作...请在"默认应用设置"页面中创建关联

    问题发现:一直使用的一款软件--火柴,这两天忽然发现通过ctrl + 回车快捷键无法进入到文件所在的目录中(之前几天印象中还可以使用该功能).后来测试又发现无法打开网易云音乐中下载的音乐而进入到该音乐 ...