博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Leetcode——Trapping Rain Water
阅读量:2338 次
发布时间:2019-05-10

本文共 3055 字,大约阅读时间需要 10 分钟。

题目描述

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.

给出n个非负整数,表示一个立面图,每一个条形图的宽度是1,计算下雨之后这个条形图能够存多少水

在这里插入图片描述

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped.

上面那个立面图是用一组数组[0,1,0,2,1,0,1,3,2,1,2,1].在这个情况下,6个单元的雨水被填满。

思路分析

  • 来源:由简入繁的思路去探讨解题思路,由最初的只有三条线,变为后来的四条线,然后再变为后来的五条线,直到最后
  • 方法一:间距扫描,将start定在某个点,然后让end从start的位置开始出发,扫描所有的点,知道遇到第一个等于或者大于start的线,开始计算面积。
    • 问题:如果start定位的数线比较高,end直接到达末尾都没有找到比其高的竖线,就结束循环,中间的面积就没有计算,造成右部侧漏。
  • 方法二:找到所有的极大值,两个极大值之间一定形成了凹谷,然后计算面积
    • 问题:这完全是没有的任何作用的,只是讲问题简化了,并没有解决问题
  • 方法三:结合前面两种方法。找出最大值,分别从最大值的左右两侧向最大值进行遍历。用最大值当做最高墙,防止左右侧漏。

我的代码

#include 
#include
int trap(int *height,int heightSize);int main(){
//今日份leetcode int p[] = {
0,1,0,2,1,0,1,3,2,1,2,1}; printf("%d \n",trap(p,12)); return 0;}int trap(int *height, int heightSize){
int container = 0; //表示该条件下雨水的体积 int start = 0; //间距扫描的开始端 int end = 1; //间距扫描的结束端 int obstacle = 0; //计算障碍物的体积 int maxIndex = 0; //判定直接返回0的情况 if(heightSize < 3) {
return 0; } //找到最高墙,防止侧漏 for(int i = 0 ;i < heightSize;i++) {
if(height[i] > height[maxIndex]) {
maxIndex = i; } } //从最高墙的左侧开始遍历 while(start <= maxIndex && end <= maxIndex) {
if(height[start] > height[end]) {
obstacle += height[end]; } else {
container = container + height[start] * (end - start - 1) - obstacle; obstacle = 0; start = end; } end ++; } start = heightSize - 1,end = start - 1,obstacle = 0; //从最高墙的右侧开始遍历 while(start >= maxIndex && end >= maxIndex) {
if(height[start] > height[end]) {
obstacle += height[end]; } else {
container = container + height[start] * (start - end - 1) - obstacle; obstacle = 0; start = end; } end --; } return container;}

分析与总结

  • 既然已经简化了问题,从仅仅有三条线进行考虑,那就会出现好几种情况,我没有完全考虑到这些情况。仅仅是得到了一种问题解答便结束思考。需要改正。

借鉴——Terrible Whiteboard在YouTuBe上传的视频

双向遍历,两线相减

在这里插入图片描述

在这里插入图片描述

  • 从左往右进行一次扫描和从右向左进行扫描,分别生成了两个数组,然后进行依次取最小值,再减去底部的建筑的面积,得到对应的水的面积。

代码实现

int trap(vector
& height){
if(height == null) return 0; int ans = 0; int size = height.size(); vector
left_max(size), right_max(size); left_max[0] = height[0]; for (int i = 1; i < size; i++) {
left_max[i] = max(height[i], left_max[i - 1]); } right_max[size - 1] = height[size - 1]; for (int i = size - 2; i >= 0; i--) {
right_max[i] = max(height[i], right_max[i + 1]); } for (int i = 1; i < size - 1; i++) {
ans += min(left_max[i], right_max[i]) - height[i]; } return ans;}
暴力破解brute force
  • 逐步遍历所有的元素,对每一个元素i重复一下的操作:
    • 从当前元素向左遍历找最大的元素MAX_LEFT
    • 从当前元素向右遍历找最大的元素MAX_RIGHT
    • 在MAX_LEFT和MAX_RIGHT中找较小的那个值min
    • 然后用min减去当前的值i,并将所有的值进行累加,即为最终答案

转载地址:http://xggpb.baihongyu.com/

你可能感兴趣的文章
状态栏和导航栏显示在iOS 7中我视图的边界上
查看>>
backbone.js的目的是什么?
查看>>
instanceof和Class.isAssignableFrom(...)有什么区别?
查看>>
使用AngularJS的ng-options使用select
查看>>
解析JSON时出现“意外令牌o”错误[重复]
查看>>
如何在PHP中获取文件扩展名? [重复]
查看>>
Scalaz迭代:“提升”`EnumeratorT`以匹配`IterateeT`为“更大”的monad
查看>>
我应该如何在OSX上设置JAVA_HOME
查看>>
如何显示过滤的ng-repeat数据的长度
查看>>
@import vs #import - iOS 7
查看>>
如何使用C#解析JSON?
查看>>
如何从MySQL中的表中删除列
查看>>
我已经安装了哪个版本的Python?
查看>>
ng-if和ng-show / ng-hide有什么区别
查看>>
将Java InputStream的内容写入OutputStream的简便方法
查看>>
用Java复制文件的标准简洁方法?
查看>>
管理webpack中的jQuery插件依赖项
查看>>
删除可能不存在的文件的大多数pythonic方式
查看>>
如何在Eclipse中为Java文本编辑器更改字体大小?
查看>>
我们应该@Override接口的方法实现吗?
查看>>