Given n non-negative integers a1a2, ..., an, where each represents a point at coordinate (iai). n vertical lines are drawn such that the two endpoints of line i is at (iai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

给定n条线段,每条线段的端点为(i,0)和(i,a[i]),现在需要在这n条线段中选择两条并与x轴组成一个水桶,求最大容量的水桶的容量(面积)。

暴力的方法就是直接枚举两条线段,找最大面积,这样复杂度是O(n^2)的。(没想到leetOJ居然还有稍强的数据,感觉是故意卡死这个复杂度的方法的。。)

我换了一个思路后,想到由于最后的最大面积一定是以某一个线段为桶的一侧(可能是左侧或者右侧)并且刚好淹没这条线段,那我们只需要枚举每条线段,然后找出这条线段左侧(或者右侧)比它高的最左(最右)的一个线段的位置,然后计算面积,并记录最大面积即可。

找到左侧比当前线段要高的最左侧线段的方法,可以直接将每个线段先按高度从大到小,再按坐标从小到大排序,然后扫描数组,记录 到当前的最小坐标,由于后扫描到的线段高度一定比先扫描到的高度小,所以只需要记录前面的坐标的最小值,便是当前线段的最左侧线段的坐标。时间复杂度O(nlogn)空间O(n)。

官网给出的标准方法,由于智力有限并不能想到,但是对其正确性还是可以给出证明。方法如下:

令指针i,j指向数组的开头和结尾,然后每次选取height[i]和height[j]较小的那个指针,并将指针想中间位置移动以为,并重新计算面积。(时间复杂度O(n),空间复杂度O(1))。

虽然我不能对这个方法有比较好的启发式的思维来想到,但是我至少还是得对其正确性给出证明,我的方法如下:

令a(i,j)表示线段i和j组成的面积(即a(i,j)=(j - i) * min{height(i), height(j)}),令DP(i,j)表示区间[i,j]的最大答案,则有:

DP(i,j) = max{DP(i+1,j), DP(i, j-1), a(i, j)}

只要证明当height(i) <= height(j)时,DP(i,j) = max{DP(i+1,j),a(i,j)}恒成立即可。

证明过程只需要分情况讨论即可:

1、若a(i,j) == DP(i,j) 这时结论显然成立。

2、若a(i,j) < DP(i,j)

1) 若DP(i+1, j-1) == DP(i,j)  这时,由于DP(i+1,j) >= DP(i+1, j-1),这时结论成立。

2) 若DP(i+1, j-1) < DP(i,j)  这时有DP(i,j) = max{DP(i+1,j), DP(i, j-1)}

因为DP(i + 1,j) = max{DP(i+1,j-1), a(i+1,j), a(i+2, j), ... , a(j - 1, j), a(j, j)}

同时DP(i, j - 1) = max{DP(i+1,j-1), a(i, i), a(i,i+1), a(i, i+2), ... , a(i, j - 1)}

因为height(i) <= height(j) 所以有max{a(i, i), a(i,i+1), a(i, i+2), ... , a(i, j - 1)} <= a(i, j) < DP(i, j)恒成立。

所以 DP(i, j) = DP(i+1, j)。得证。

 public class Solution {
public int maxArea(int[] height) {
int maxarea = 0, l = 0, r = height.length - 1;
while (l < r) {
maxarea = Math.max(maxarea, Math.min(height[l], height[r]) * (r - l));
if (height[l] < height[r])
l++;
else
r--;
}
return maxarea;
}
}

思维题(两点逼近)LeetCode11 Container with Most Water的更多相关文章

  1. Leetcode11 Container With Most Water 解题思路 (Python)

    今天开始第一天记录刷题,本人编程小白,如果有写的不对.或者能更完善的地方请个位批评指正! 准备按tag刷,第一个tag是array: 这个是array的第一道题:11. Container With ...

  2. LeetCode11 Container With Most Water

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

  3. Leetcode11.Container With Most Water盛最多水的容器

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...

  4. UVA.10881 Piotr's Ants (思维题)

    UVA.10881 Piotr's Ants (思维题) 题意分析 有一根长度为L cm的木棍,上有n只蚂蚁,蚂蚁要么向左爬,要么向右,速度均为1cm/s,若2只蚂蚁相撞,则蚂蚁同时调头.求解第T秒时 ...

  5. Atcoder Grand Contest 001E - BBQ Hard(组合意义转化,思维题)

    Atcoder 题面传送门 & 洛谷题面传送门 Yet another 思维题-- 注意到此题 \(n\) 数据范围很大,但是 \(a_i,b_i\) 数据范围很小,这能给我们什么启发呢? 观 ...

  6. zoj 3778 Talented Chef(思维题)

    题目 题意:一个人可以在一分钟同时进行m道菜的一个步骤,共有n道菜,每道菜各有xi个步骤,求做完的最短时间. 思路:一道很水的思维题, 根本不需要去 考虑模拟过程 以及先做那道菜(比赛的时候就是这么考 ...

  7. cf A. Inna and Pink Pony(思维题)

    题目:http://codeforces.com/contest/374/problem/A 题意:求到达边界的最小步数.. 刚开始以为是 bfs,不过数据10^6太大了,肯定不是... 一个思维题, ...

  8. ZOJ 3829 贪心 思维题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...

  9. 洛谷P4643 [国家集训队]阿狸和桃子的游戏(思维题+贪心)

    思维题,好题 把每条边的边权平分到这条边的两个顶点上,之后就是个sb贪心了 正确性证明: 如果一条边的两个顶点被一个人选了,一整条边的贡献就凑齐了 如果分别被两个人选了,一作差就抵消了,相当于谁都没有 ...

随机推荐

  1. rsync+inotify文件同步

    rsync+inotify文件同步 在服务器中,通常结合计划任务.shell脚本来执行本地备份.为了进一步提高备份的可靠性,使用异地备份也是非常重要的,利用rsync工具,可以实现快速.高效的异地备份 ...

  2. 用MVVM模式开发中遇到的零散问题总结(1)

    https://www.cnblogs.com/tong-tong/archive/2011/11/28/2250948.html

  3. mongoDB——自动分片(转)

    原文地址:http://www.lanceyan.com/tech/arch/mongodb_shard1.html 在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会 ...

  4. Mysql批量导入约束报错

    SET foreign_key_checks = 0;   禁用外键,在文件顶部加 SOURCE dump_file_name;      进行SQL执行 SET foreign_key_checks ...

  5. 『Sklearn』特征向量化处理

    『Kaggle』分类任务_决策树&集成模型&DataFrame向量化操作 1 2 3 4 5 6 7 8 9 '''特征提取器''' from sklearn.feature_extr ...

  6. Andriod给textview文本关键字循环标亮加粗

    在开发中,搜索到得关键字信息在展示时,通常需要标亮加粗,如下图(截取自蓝鲸医生助手搜索后的结果) 在文本中,关键字是“嘎”,所有“嘎”字都标亮加粗,标亮就是换种颜色.这里就要用到SpannableSt ...

  7. linux make virtual memory more efficient three components

    Page Cache This is used to speed up access to images and data on disk. As pages are read into memory ...

  8. 51nod1513

    题解: 更据题意,在树上深度为没一个数的都放在一起,要用的时候二分出来,看结果 用c++的数据结构 代码: #include<bits/stdc++.h> using namespace ...

  9. HTML5之pushstate、popstate操作history,无刷新改变当前url

    一.认识window.history window.history表示window对象的历史记录,是由用户主动产生,并且接受javascript脚本控制的全局对象.window对象通过history对 ...

  10. 用UILabel实现文字滚动播放(跑马灯)效果

    - (void)viewDidLoad { [super viewDidLoad]; //数据源 self.messageArray = [NSArray arrayWithObjects: &quo ...