每日算法之三十三: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.

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. Thanks Marcos for contributing
this image!
图中浅颜色的就是雨水的含量,从图中我们不难发现,在每一列有水的雨水含量就是这一列左右两側最高的两个柱子中的较矮的柱子和当前列的高度差。这样我们就能逐次计算出来分列的含量。当然,我们能够在计算每一列的时候都计算一遍两側的最大值,可是这样是浪费时间的,我们能够分治解决,先求解出最高的柱子,这样这一柱子在一定时刻内能够当做当中一側的最值,逐渐缩小范围就可以。以下是自己写的代码,可能比較乱,可是思想还是能够感受一下的,在最后会贴出来大牛们写的高质量代码。
<span style="font-size:18px;">class Solution {
public:
int max_value(int a,int b)
{
return a>b?a:b;
}
int max_element_position(int A[],int begin,int end)
{
int max = A[begin];
int pos = begin;
for(int i = begin+1;i<=end;i++)
if(A[i]>max)
{
max = A[i];
pos = i;
}
return pos;
}
int water(int A[],int start,int left_max,int end,int right_max)
{
int left = 0,right = 0,mid = 0;
if(start == end)
{
if(left_max>A[start] && right_max>A[start])
return min(left_max,right_max) - A[start];
else
return 0;
}
int max = max_element_position(A,start,end);
if(A[max]<left_max && A[max]<right_max)//这里要注意,中间的最大值也可能上面存储水
{
mid = min(left_max,right_max) - A[max];
}
if(max-1 >= start)
left = water(A,start,left_max,max-1,max_value(right_max,A[max]));
if(max+1 <= end)
right = water(A,max+1,max_value(left_max,A[max]),end,right_max);
return left+right+mid;
}
int trap(int A[], int n) {
if(n<=2)
return 0;
return water(A,0,0,n-1,0);
}
};</span>
以下的方法确实是非常理解了非常多,不错不错。
int trap(int A[], int n) {
// Note: The Solution object is instantiated only once.
if(A==NULL || n<1)return 0;
int maxheight = 0;
vector<int> leftMostHeight(n);
for(int i =0; i<n;i++)
{
leftMostHeight[i]=maxheight;
maxheight = maxheight > A[i] ? maxheight : A[i];
}
maxheight = 0;
vector<int> rightMostHeight(n);
for(int i =n-1;i>=0;i--)
{
rightMostHeight[i] = maxheight;
maxheight = maxheight > A[i] ? maxheight : A[i];
}
int water = 0;
for(int i =0; i < n; i++)
{
int high = min(leftMostHeight[i],rightMostHeight[i])-A[i];
if(high>0)
water += high;
}
return water;
}
每日算法之三十三:Trapping Rain Water的更多相关文章
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- LeetCode:Container With Most Water,Trapping Rain Water
Container With Most Water 题目链接 Given n non-negative integers a1, a2, ..., an, where each represents ...
- 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] 42. Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [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 ...
- [LintCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...
- 有意思的数学题:Trapping Rain Water
LeetCode传送门 https://leetcode.com/problems/trapping-rain-water/ 目标:找出积木能容纳的水的“面积”,如图中黑色部分是积木,蓝色为可容纳水的 ...
随机推荐
- boost asio 异步实现tcp通讯
---恢复内容开始--- asioboost 目录(?)[-] 一前言 二实现思路 通讯包数据结构 连接对象 连接管理器 服务器端的实现 对象串行化 一.前言 boost asio可算是一个简 ...
- 临界段CCriticalSection的使用
类CCriticalSection的对象表示一个“临界区”,它是一个用于同步的对象,同一时刻仅仅同意一个线程存取资源或代码区.临界区在控制一次仅仅有一个线程改动数据或其他的控制资源时很实用.比如,在链 ...
- Android应用开发之(通过ClipboardManager, ClipData进行复制粘贴)
在开发一些系统应用的时候,我们会用到Android的剪贴板功能,比如将文本文件.或者其他格式的内容复制到剪贴板或者从剪贴板获取数据等操作.Android平台中每个常规的应用运行在自己的进程空间中,相对 ...
- 用VC制作应用程序启动画面
摘 要:本文提供了四种启动画面制作方法. 使用启动画面一是可以减少等待程序加载过程中的枯燥感(尤其是一些大型程序):二是 可以用来显示软件名称和版权等提示信息.怎样使用VC++制作应用程序的启动画面呢 ...
- CImage类
CImage封装了DIB(设备无关位图)的功能,因而可以让我们能够处理每个位图像素.这里介绍GDI+和CImage的一般使用方法和技巧. TAG: GDI CImage 后处理 我们知道,Vi ...
- 【Visual C++】绘图函数BitBlt的使用方法
BitBlt 该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境. 原型: BOOL BitBlt( HDC hdcDest, int nXDest, ...
- Swift - 炫酷放射弹出按钮菜单(改造自AwesomeMenu)
这个是一个第三方按钮菜单组件,原版是使用Objective-C编写的名为AwesomeMenu的组件,地址是:https://github.com/levey/AwesomeMenu 这里改造成了Sw ...
- google 搜索url详解
www.google.com [http://www.google.cn/search?q=112&hl=zh-CN&client=aff- 360daohang&hs=yhE ...
- 引用类中的enum
引用类中的enum 引用类中的enum,需要加类的域class_name::value_in_enum_name 点击(此处)折叠或打开 #include <stdio.h> #inclu ...
- SilkTest Q&A 2
Q11:SilkTest中有没有计算web页面上单词数量的函数? A11:你可以使用Clipboard函数.使用Ctrl+a和Ctrl+c,然后解析string的list. Q12:silktest的 ...