【leet-code】接雨水
给定 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】接雨水的更多相关文章
- 【Leet Code】Palindrome Number
Palindrome Number Total Accepted: 19369 Total Submissions: 66673My Submissions Determine whether an ...
- Leet Code 771.宝石与石头
Leet Code编程题 希望能从现在开始,有空就做一些题,自己的编程能力太差了. 771 宝石与石头 简单题 应该用集合来做 给定字符串J 代表石头中宝石的类型,和字符串 S代表你拥有的石头. S ...
- #Leet Code# Gray Code
描述: 要求相邻数2进制差一位 先获得n-1的列表表示小于 2^(n-1) 的符合要求的列表,加上最高位的加成 2^(n-1) 就是大于等于 2^(n-1) 的符合要求的列表,后者翻转一下就能够与前者 ...
- #Leet Code# Permutation
描述: 输出全排列 代码: class Solution: # @param num, a list of integer # @return a list of lists of integers ...
- #Leet Code# Unique Path(todo)
描述: 使用了递归,有些计算是重复的,用了额外的空间,Version 1是m*n Bonus:一共走了m+n步,例如 m = 2, n = 3 [#, @, @, #, @],所以抽象成数学问题,解是 ...
- #Leet Code# Populating Next Right Pointers in Each Node II
描述:注意需要先self.connect(right)再self.connect(left),否则会有case通不过,原因是左边递归执行时依赖与右边的next已经建立,而先执行connect(left ...
- #Leet Code# Sqrt
描述:log(n) 代码: class Solution: # @param x, an integer # @return an integer def getVal(self, begin, en ...
- #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 ...
- #Leet Code# Convert Sorted Array to Binary Search Tree
描述:递归 代码: class Solution: # @param num, a list of integers # @return a tree node def sortedArrayToBS ...
- #Leet Code# Evaluate Reverse Polish Notation
描述:计算逆波兰表达法的结果 Sample: [", "*"] -> ((2 + 1) * 3) -> 9 [", "/", & ...
随机推荐
- Python【day 9】函数入门1
1.什么是函数 函数的概念:对功能或者动作的封装 函数的好处:避免重复代码 2.函数的定义 1.函数的定义 def 函数名(形参列表): 函数体(return) 2.函数的调用 函数名(实参列表) 3 ...
- 实验吧——认真一点(绕过空格,逗号,关键字过滤等 sql盲注)
题目地址:http://ctf5.shiyanbar.com/web/earnest/index.php 过滤和拦截了某些东西,我经过多次尝试,最终构造的是 1'=(ascii(mid((select ...
- Qt中QWidget、QDialog和QMainWindow
QWidget 类是所有用户界面对象的基类.只有一个"页面" QMainWindow 是一个"窗口".含有菜单栏.状态栏.工具栏.停靠窗口.中心窗口 QDial ...
- H5离线缓存(基础)学习指南
离线缓存 application cache 1. 什么是离线缓存: 离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没有连接网络,被缓存的页面也可 ...
- CentOS7升级内核kernel5.0
升级过程: 原系统:CentOS7.3 [root@my-e450 ~]# uname -r3.10.0-514.el7.x86_64 安装必需的软件包: # yum update# yum inst ...
- Robot Framework常用关键字
虽然通过RIDE提供"填表"一样的写测试用例的方式.但它却支持强大的关键字功能,以及可以开发关键字的扩展能力. Comment 注释功能,也可以使用python中的"#& ...
- python之pip安装软件包常用命令
# pip版本号查询 pip -V # 安装软件包.格式:pip install 软件包名 pip install pygame # 安装指定版本号的软件包.格式:pip install 软件包==软 ...
- springboot搭建dubbo+zookeeper简单案例
背景:只是自己使用单机版zookeeper搭建dubbo的一个学习案例,记录成功的过程 1.搭建zookeeper坏境 使用docker来构建环境 1.1 拉取镜像:docker pull zooke ...
- django 补充 QuerySet数据类型
1 QuerySet数据类型 特点: (1) 可切片 Entry.objects.all()[:5] (2) 可迭代 : articleLis ...
- Winform----自定义控件之半透明遮罩(蒙版遮盖指定控件)
先贴运行效果图,源码点击这里下载 1.新建自定义控件 2.实现功能 namespace UserControlLib { [ToolboxBitmap(typeof(ZhLoading)) ...
