【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文件属性模块Os.path
Python文件属性模块Os.path介绍 os.path模块主要用于文件属性获取和判断,在编程中会经常用到,需要熟练掌握.以下是该模块的几种常用方法. os.path官方文档:http://docs ...
- 【python】ConnectionRefusedError: [WinError 10061]
在测试接口过程中,由于各种原因服务端返回:10061,由于目标计算机积极拒绝,无法连接. 图一 图二 造成这种返回结果的可能原因:1.代码问题2.本机代理设置问题3.本地防火墙或者安全卫士之类的设置问 ...
- NSQ端口关系以及注意事项
0.相关参考文章: 官网:https://nsq.io/ <golang实战-nsq集群入门与坑> <nsq系统架构> <NSQ消息队列> 1.启动命令 ①nsql ...
- java国际化之时区问题处理
原文:https://moon-walker.iteye.com/blog/2396035 在国际化的项目中需要处理的日期时间问题主要有两点: 1.日期时间的国际化格式问题处理: 2.日期时间的时区问 ...
- vue - 基础(1)
Vue基本用法 在学习Vue的基本用法之前,我们先简单的了解一些es6的语法 let: 特点:1.局部作用域 2.不会存在变量提升 3.变量不能重复声明 const: 特点:1.局部作用域 2.不会存 ...
- 大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫
大众点评评论数据抓取 反爬虫措施有css文字映射和字体库反爬虫 大众点评的反爬虫手段有那些: 封ip,封账号,字体库反爬虫,css文字映射,图形滑动验证码 这个图片是滑动验证码,访问频率高的话,会出 ...
- 转:宏定义的极致发挥---让你的普通C++类轻松支持IDispatch自动化接口(二)
Posted on 2011-01-13 20:44 一桶浆糊 这是上一篇博客<宏定义的极致发挥---让你的普通C++类轻松支持IDispatch自动化接口>所展示的示例代码的改进版,改进 ...
- uiautomatorviewer
uiautomatorviewer路径 /usr/local/Caskroom/android-platform-tools/29.0.1/tools/bin
- C#中的函数(一) 无参无返回值的函数
分析下C#中的函数 先写一个小例子,一个静态函数,无返回值,无形参 在第17行与20行分别下断点 F5调试运行,此时中断在第17行MyFunction(), 在第17行右键反汇编,看下反汇编代码 这里 ...
- 20180606模拟赛T4——数学游戏
数学游戏 题目描述: 小T又发脑残了,没错,她又要求奇怪的东西,这次她想知道[X,Y]之间整数有多少可以表示成K个不同的B的幂的和形势.如\(x,y,k,b=15,20,2,2\),则有: \[17= ...