LeetCode 笔记系列12 Trapping Rain Water [复杂的代码是错误的代码]
题目:Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

例如给出上图中的黑色部分(数组表示),让你求出蓝色部分。
这也是个神题。。。当然对小白我来说。
想了半天,是不是遍历数组呢,然后依次计算当前bar构成的container大小。问题在于,这个方法要考虑的边界条件太多了。写了一个很复杂的算法,还用到了stack来记录碎片的蓝色部分,结果最后还是miss很多情况。
后来想了一个复杂度比较高的但是代码看来了比较简单的算法。觉得简直要被BS屎了。但是还是记录下来以村托牛人的牛。
想的方法我取名叫俄罗斯方块法,为啥,你马上就晓得鸟。
把上面的图图,instead of看成一个个柱子,我看成一排排的方块。

然后,对每一行,我数数有多少蓝色的方块,累加起来,不就是总共的蓝色部分了么。
这个复杂度有点高,取决与最大的元素的值*O(n)。
解法一:
public static int trap(int[] A){
int i = 0;
int j = A.length - 1;
int sumArea = 0;
while(i + 1 < j){
//首先找到两边都不是0的位置
while(A[i] <= 0 && i < j)i++;
while(A[j] <= 0 && i < j)j--;
//然后数数当前行有多少蓝色方块,也是就0的个数啦。
//同时记录最小值
int min = Integer.MAX_VALUE;
for(int k = i; k < j;k++){
if(A[k] == 0) sumArea += 1;
if(A[k] < min) min = A[k];
}
//为记录下一行做准备,消除俄罗斯方块。。。。
int step = Math.max(min, 1);
for(int k = i; k <= j; k++){
if(A[k] > 0)A[k]-= step;
}
}
return sumArea;
}
然后大集合就可耻地潮湿了。
leetcode的牛人是怎么做的呢?人家不仅有O(n)的解法,而且constant space。膜拜。
首先,找到最高的一个柱子,例如例子中的3。

然后遍历左半边。从i=0开始靠近mid,遍历过程中维护一个curHeight,表示这当前遇到的最大的height值;如果当前的bar的height小于最大值,那么当前的bar能贡献的water就是height - curMaxHeight。否则的话,更新curMaxHeight。
为了更好理解这个算法,我们来track下这个过程:


最后遍历右半边。过程是一模一样的,只不过i从最右边靠近Mid。
解法二
代码如下:
public static int trap2(int[] A){
if(A.length <= 1) return 0;
int curMaxHeight = 0;
int water = 0;
int mid = 0;
for(int i = 0; i < A.length;i++){
if(A[i] > A[mid]) mid = i;
}
for(int i = 0; i < mid; i++){
if(A[i] < curMaxHeight){
water += curMaxHeight - A[i];
}else curMaxHeight = A[i];
}
curMaxHeight = 0;
for(int i = A.length - 1; i > mid; i--){
if(A[i] < curMaxHeight){
water += curMaxHeight -A[i];
}else curMaxHeight = A[i];
}
return water;
}
其实,本质上来说,第一步保障了左右两边的水总是能“放进去”,因为大板子在中间档着嘛。
Faint,我写到这里,想到这个代码其实也是蛮简单的,为啥我就没想到呢!唉。。。
总结下:
复杂的代码是错误的代码。没有例外。
LeetCode 笔记系列12 Trapping Rain Water [复杂的代码是错误的代码]的更多相关文章
- leetcode 第41题 Trapping Rain Water
题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, co ...
- LeetCode(42)Trapping Rain Water
题目 Given n non-negative integers representing an elevation map where the width of each bar is 1, com ...
- LeetCode: Trapping Rain Water 解题报告
https://oj.leetcode.com/problems/trapping-rain-water/ Trapping Rain WaterGiven n non-negative intege ...
- [LeetCode] Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [Leetcode][Python]42: Trapping Rain Water
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...
- leetcode#42 Trapping rain water的五种解法详解
leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...
- [array] leetcode - 42. Trapping Rain Water - Hard
leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...
- [LeetCode] 接雨水,题 Trapping Rain Water
这题放上来是因为自己第一回见到这种题,觉得它好玩儿 =) Trapping Rain Water Given n non-negative integers representing an eleva ...
随机推荐
- hibernate中一些属性对操作的影响
1 inverse,在一对多中使用,表示是否有关联关系控制权.对于保存.删除数据有影响. 2 cascade,表示级联操作 save-update 表示级联保存和更新 delete 表示级联删除 al ...
- Redis 实现接口访问频率限制
为什么限制访问频率 做服务接口时通常需要用到请求频率限制 Rate limiting,例如限制一个用户1分钟内最多可以范围100次 主要用来保证服务性能和保护数据安全 因为如果不进行限制,服务调用者可 ...
- 利用docker-maven-plugin快速交测
目的 由开发环境交测的时候,通过docker镜像简化环境搭建及项目部署的过程. 环境描述 项目开发环境: windowns7 在windowns7中通过VMware Workstation安装Cent ...
- COM方式实现C++调用C#代码的一些总结
首先这个测试没成功,只在本机上可行,在不同机器上测试失败.可能是GUID不对或者没注册成功. 既然已经花了一上午时间去研究,还是总结一下 1.网上说要创建一个snk证书,但不创建也可以.只不过不能放入 ...
- Atitit.mysql oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server..
Atitit.mysql oracle with as模式临时表模式 CTE 语句的使用,减少子查询的结构性 mssql sql server.. 1. with ... as (...) 在mys ...
- CXAnimation.h动画类
/**************************************************************************** 使用一个CCAnimation对象可以CCS ...
- HTML中label的两种使用方法
如果您在 label 元素内点击文本,就会触发此控件.就是说,当用户选择该标签时,浏览器就会自动将焦点转到和标签相关的表单控件上. 有两种使用方法: 方法1: <label for=" ...
- 用 malloc 或 new 申请内存之后,应该立即检查指针值是否为 NULL
用 malloc 或 new 申请内存之后,应该立即检查指针值是否为 NULL. 防止使用指针值为 NULL 的内存. #include <iostream> #include <s ...
- html的a标签的 href 和 onclick。
主要用于给超链接添加点击事件. aa.html <html> <body> <span>this si</span> </body> < ...
- 用 HTML5+ payment方法支付宝支付遇到的坑
用 HTML5+ payment方法碰到的第一个坑就是如果是支付宝的话签约那种支付方式. 因为 Dcloud的文档没有更新的原因你可以看到他们说的都是‘移动支付’,但是你去支付宝平台的时候看到的根本就 ...