给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 感谢 Marcos 贡献此图。

示例:

输入: [0,1,0,2,1,0,1,3,2,1,2,1]

输出: 6

分析:

解法1:暴力法

对每个元素取其左右两边的最大值的最小值,然后减去当前值

时间复杂度:O(N^2),对每个元素都需要取其左右两边的最大值

空间复杂度:O(1)

class Solution
{
public:
int trap(vector<int>& v)
{
int ans=0;
if(v.size()==0)
return 0;
for(int i=1; i<v.size()-1; i++)
{
int leftmax=0;
for(int j1=i-1; j1>=0; j1--) //取其左边元素的最大值
{
leftmax=max(leftmax,v[j1]);
}
int rightmax=0;
for(int j2=i+1; j2<v.size(); j2++) //取其右边元素的最大值
{
rightmax=max(rightmax,v[j2]);
}
int x=min(leftmax,rightmax)-v[i];//取两个最大值的最小值
if(x>0)//能够储水
{
ans+=x;//符合要求则加上
}
}
return ans;
}
}

解法2:动态规划

暴力法每次都有寻找其左右两边最大元素的最小值

我们可以通过两次O(N)的遍历记录下当前元素的左右两边最大值的最小值

时间复杂度:O(N)

空间复杂度:O(N)

class Solution
{
public:
int trap(vector<int>& v)
{
int ans=0;
if(v.size()==0)
return 0;
int n=v.size();
int dp[n];//dp[i]:当前元素i左右两边最大值的最小值
dp[0]=0;
dp[n-1]=0; for(int i=1; i<n-1; i++) //左边最大值
{
dp[i]=max(dp[i-1],v[i-1]);
}
for(int i=n-2; i>=1; i--) //右边最大值和当前左边最小值比较
{
dp[i]=min(dp[i],max(dp[i+1],v[i+1]));
}
for(int i=1; i<n-1; i++) //符合要求累加即可
{
if(dp[i]-v[i]>0)
ans+=dp[i]-v[i];
}
return ans;
}
}

解法3:左右双指针法



先找到最高点k,k把数组分为了左右两部分

对左半部分的当前值来说:

如果当前值大于当前值左边的最大值,那么水就会向左边流走,当前值就储存不了水,只能更新一下左边最大值

如果当前值不大于当前值左边的最大值,那么就可以储存住水,水的量就是当前左边最大值减去当前值

对右半部分的当前值来说:

如果当前值小于当前值右边的最大值,那么水就会向右边流走,当前值就储存不了水,只能更新一下右边最大值

如果当前值不大于当前值右边的最大值,那么就可以储存住水,水的量就是当前右边最大值减去当前值

注意,左边最大值和右边最大值都不是相对于整个左边部分或右边部分来说的

左边最大值是相当于当前元素的左边的所有元素来说的

右边最大值是相当于当前元素的右边的所有元素来说的

时间复杂度:O(N)

空间复杂度:O(1)

class Solution
{
public:
int trap(vector<int>& v)
{
int ans=0;
int n=v.size();
if(n==0)
return 0;
int k=0;
for(int i=1; i<n; i++) //找到最高点k,k把数组分为左右两部分(都不包含k)
{
if(v[i]>v[k])
k=i;
}
int maxleft=0;//左边最大值指针
for(int i=1; i<k; i++) //左半部分
{
if(v[maxleft]<v[i])//不能储水,水向左边流走了
maxleft=i;//更新左边最大值
else
ans+=(v[maxleft]-v[i]);//可以储存水
}
int maxright=n-1;//右边最大值指针
for(int i=n-2; i>k; i--) //右半部分
{
if(v[maxright]<v[i])//不能储存水。水向右边流走了
maxright=i;//更新右边最大值
else
ans+=(v[maxright]-v[i]);//可以储存水
}
return ans;
}
}

【leet-code】接雨水的更多相关文章

  1. 【Leet Code】Palindrome Number

    Palindrome Number Total Accepted: 19369 Total Submissions: 66673My Submissions Determine whether an ...

  2. Leet Code 771.宝石与石头

    Leet Code编程题 希望能从现在开始,有空就做一些题,自己的编程能力太差了. 771 宝石与石头 简单题 应该用集合来做 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S  ...

  3. #Leet Code# Gray Code

    描述: 要求相邻数2进制差一位 先获得n-1的列表表示小于 2^(n-1) 的符合要求的列表,加上最高位的加成 2^(n-1) 就是大于等于 2^(n-1) 的符合要求的列表,后者翻转一下就能够与前者 ...

  4. #Leet Code# Permutation

    描述: 输出全排列 代码: class Solution: # @param num, a list of integer # @return a list of lists of integers ...

  5. #Leet Code# Unique Path(todo)

    描述: 使用了递归,有些计算是重复的,用了额外的空间,Version 1是m*n Bonus:一共走了m+n步,例如 m = 2, n = 3 [#, @, @, #, @],所以抽象成数学问题,解是 ...

  6. #Leet Code# Populating Next Right Pointers in Each Node II

    描述:注意需要先self.connect(right)再self.connect(left),否则会有case通不过,原因是左边递归执行时依赖与右边的next已经建立,而先执行connect(left ...

  7. #Leet Code# Sqrt

    描述:log(n) 代码: class Solution: # @param x, an integer # @return an integer def getVal(self, begin, en ...

  8. #Leet Code# Best Time to Buy and Sell Stock

    描述:数组 A,对于 i < j, 找到最大的 A[j] - A[i] 代码: class Solution: # @param prices, a list of integer # @ret ...

  9. #Leet Code# Convert Sorted Array to Binary Search Tree

    描述:递归 代码: class Solution: # @param num, a list of integers # @return a tree node def sortedArrayToBS ...

  10. #Leet Code# Evaluate Reverse Polish Notation

    描述:计算逆波兰表达法的结果 Sample: [", "*"] -> ((2 + 1) * 3) -> 9 [", "/", & ...

随机推荐

  1. git操作:查看分支、删除本地分支和远程分支

    1.查看本地分支:git branch 2.查看远程分支:git branch -r 或 git branch --remote 3.查看本地和远程的所有分支:git branch -a 4.删除本地 ...

  2. centos7设置时间

    1.查看时间时区 date 2.修改时区 timedatectl set-timezone Asia/Shanghai # 设置系统时区为上海 3.安装ntp 联网校准时间 yum install n ...

  3. vue中的---MVVM(面试必问)

    M---Model  (数据) V---View (视图) VM---VIewModel  (转换器) VIewModel主要做两件事: 1.把 Model 中的数据绑定到View(视图层). 2.监 ...

  4. Redis 分布式锁的正确打开方式

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  5. UNITY Serializer 序列化 横向对比

    UNITY Serializer 序列化 横向对比 关于序列化,无论是.net还是unity自身都提供了一定保障.然而人总是吃着碗里想着锅里,跑去github挖个宝是常有的事.看看各家大佬的本事.最有 ...

  6. Nginx 核心配置-作为上传服务器配置

    Nginx 核心配置-作为上传服务器配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.关键参数说明 client_max_body_size 1m: 设置允许客户端上传单 ...

  7. recon-ng打开后显示No modules enabled/installed

    今天开始学习使用 recon-ng,进去后发现这么一行: 原因 在网上找了挺久,发现了这篇文章:Recon-ng v5 Tutorial, 原来是更新的原因,需要我们自行安装模块(旧版本是自带了许多模 ...

  8. LCD编程框架组织

    看下面的代码,你会发现韦老师这种组织与内核框架的组织是一脉相承的. led.c #define LCD_NUM 10 static p_lcd_params p_array_lcd[LCD_NUM]; ...

  9. maven 配置文件

    <properties> <project.builder.sourcesEncoding>UTF-8</project.builder.sourcesEncoding& ...

  10. 如何让wordpress后台搜索只匹配搜索文章标题

    今天编辑小美眉问网站wordpress后台能不能实现只搜索标题,这个问题怎么可能难到ytkah呢?打开Stack Overflow一顿狂搜,总数有解决方案了,哈哈哈!一起来看看怎么操作吧. 打开主题目 ...