思维题(两点逼近)LeetCode11 Container with Most Water
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) 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的更多相关文章
- Leetcode11 Container With Most Water 解题思路 (Python)
今天开始第一天记录刷题,本人编程小白,如果有写的不对.或者能更完善的地方请个位批评指正! 准备按tag刷,第一个tag是array: 这个是array的第一道题:11. Container With ...
- LeetCode11 Container With Most Water
题意: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, a ...
- Leetcode11.Container With Most Water盛最多水的容器
给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两条线, ...
- UVA.10881 Piotr's Ants (思维题)
UVA.10881 Piotr's Ants (思维题) 题意分析 有一根长度为L cm的木棍,上有n只蚂蚁,蚂蚁要么向左爬,要么向右,速度均为1cm/s,若2只蚂蚁相撞,则蚂蚁同时调头.求解第T秒时 ...
- Atcoder Grand Contest 001E - BBQ Hard(组合意义转化,思维题)
Atcoder 题面传送门 & 洛谷题面传送门 Yet another 思维题-- 注意到此题 \(n\) 数据范围很大,但是 \(a_i,b_i\) 数据范围很小,这能给我们什么启发呢? 观 ...
- zoj 3778 Talented Chef(思维题)
题目 题意:一个人可以在一分钟同时进行m道菜的一个步骤,共有n道菜,每道菜各有xi个步骤,求做完的最短时间. 思路:一道很水的思维题, 根本不需要去 考虑模拟过程 以及先做那道菜(比赛的时候就是这么考 ...
- cf A. Inna and Pink Pony(思维题)
题目:http://codeforces.com/contest/374/problem/A 题意:求到达边界的最小步数.. 刚开始以为是 bfs,不过数据10^6太大了,肯定不是... 一个思维题, ...
- ZOJ 3829 贪心 思维题
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3829 现场做这道题的时候,感觉是思维题.自己智商不够.不敢搞,想着队友智商 ...
- 洛谷P4643 [国家集训队]阿狸和桃子的游戏(思维题+贪心)
思维题,好题 把每条边的边权平分到这条边的两个顶点上,之后就是个sb贪心了 正确性证明: 如果一条边的两个顶点被一个人选了,一整条边的贡献就凑齐了 如果分别被两个人选了,一作差就抵消了,相当于谁都没有 ...
随机推荐
- rsync+inotify文件同步
rsync+inotify文件同步 在服务器中,通常结合计划任务.shell脚本来执行本地备份.为了进一步提高备份的可靠性,使用异地备份也是非常重要的,利用rsync工具,可以实现快速.高效的异地备份 ...
- 用MVVM模式开发中遇到的零散问题总结(1)
https://www.cnblogs.com/tong-tong/archive/2011/11/28/2250948.html
- mongoDB——自动分片(转)
原文地址:http://www.lanceyan.com/tech/arch/mongodb_shard1.html 在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会 ...
- Mysql批量导入约束报错
SET foreign_key_checks = 0; 禁用外键,在文件顶部加 SOURCE dump_file_name; 进行SQL执行 SET foreign_key_checks ...
- 『Sklearn』特征向量化处理
『Kaggle』分类任务_决策树&集成模型&DataFrame向量化操作 1 2 3 4 5 6 7 8 9 '''特征提取器''' from sklearn.feature_extr ...
- Andriod给textview文本关键字循环标亮加粗
在开发中,搜索到得关键字信息在展示时,通常需要标亮加粗,如下图(截取自蓝鲸医生助手搜索后的结果) 在文本中,关键字是“嘎”,所有“嘎”字都标亮加粗,标亮就是换种颜色.这里就要用到SpannableSt ...
- 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 ...
- 51nod1513
题解: 更据题意,在树上深度为没一个数的都放在一起,要用的时候二分出来,看结果 用c++的数据结构 代码: #include<bits/stdc++.h> using namespace ...
- HTML5之pushstate、popstate操作history,无刷新改变当前url
一.认识window.history window.history表示window对象的历史记录,是由用户主动产生,并且接受javascript脚本控制的全局对象.window对象通过history对 ...
- 用UILabel实现文字滚动播放(跑马灯)效果
- (void)viewDidLoad { [super viewDidLoad]; //数据源 self.messageArray = [NSArray arrayWithObjects: &quo ...