42.Trapping Rain Water---dp,stack,两指针
题目链接:https://leetcode.com/problems/trapping-rain-water/description/
题目大意:与84题做比较,在直方图中计算其蓄水能力。例子如下:

法一(借鉴):暴力,还是很难想到的,需要推理数学功底。因为这里暴力的前提条件是:计算每个点的蓄水能力,相当于求解,min(每个点左边的最大高度,每个点右边的最大高度)-当前值。也就是这里,把一整个蓄水池的分解成一个点一个点的蓄水能力。代码如下(耗时150ms):
public int trap(int[] height) {
int res = 0;
for(int i = 0; i < height.length; i++) {
int left = height[i], right = height[i];
//找左边最大高度
for(int j = i - 1; j >= 0; j--) {
left = Math.max(left, height[j]);
}
//找右边最大高度
for(int j = i + 1; j < height.length; j++) {
right = Math.max(right, height[j]);
}
//计算蓄水
res += Math.min(left, right) - height[i];
}
return res;
}
法二(借鉴):一维dp,思想与上面暴力相同,都是取左右两边高度的较小者然后与当前值比较,如果大,则可以蓄水。代码如下(耗时22ms):
public int trap(int[] height) {
int dp[] = new int[height.length];
int ma = 0, res = 0;
//记录i值左边的最大高度
for(int i = 0; i < height.length; i++) {
dp[i] = ma;
//更新左边最大高度
ma = Math.max(ma, height[i]);
}
//更新计算i值右边的最大高度
ma = 0;
for(int i = height.length - 1; i >= 0; i--) {
//在左边和右边最大高度中取较小者
dp[i] = Math.min(dp[i], ma);
//更新右边
ma = Math.max(ma, height[i]);
//如果两边高度比当前高度高,则表示可以蓄水
if(dp[i] > height[i]) {
res += dp[i] - height[i];
}
}
return res;
}
法三(借鉴):stack,与84题stack做法比较,此题在压栈的时候是降序高度压栈,当当前高度>s.peek()时,可以蓄水,栈顶第一个元素为坑最低高度,栈顶第二个元素为左边界,当前高度为右边界,坑深为min(左高度,右高度)-坑最低高度。代码如下(耗时30ms):
//入栈递减高度,当当前高度>s.peek()时,可以蓄水,栈顶第一个元素为坑最低高度,栈顶第二个元素为左边界,当前高度为右边界,坑深为min(左高度,右高度)-坑最低高度
public int trap(int[] height) {
Stack<Integer> s = new Stack<Integer>();
int res = 0;
for(int i = 0; i < height.length; i++) {
//循环查找在当前高度下,是否可以蓄水
while(!s.isEmpty() && height[i] > height[s.peek()]) {
int cur = s.pop();
//如果栈空,说明没有左边界,没法蓄水,所以直接break
if(s.isEmpty()) {
break;
}
//计算蓄水,此时不再是按照前面的方法,分点计算竖状蓄水能力,而是按照整块的蓄水能力计算的,也就是普通思维的按照蓄水池的长*宽来计算的
res += (i - s.peek() - 1) * (Math.min(height[s.peek()], height[i]) - height[cur]);
}
//如果比栈顶高度小,压栈
s.push(i);
}
return res;
}
法四(借鉴):两个指针移动,比较左指针指向的高度和右指针指向的高度,记录较小者,如果左指针指向的较小,则从左往右遍历,如果右指针指向的较小,则从右往左遍历,如果遍历到的当前值比较小者小,则表示可以蓄水:较小者-当前值。代码如下(22ms):
//定义两个指针,左指针与右指针的值进行比较,记录较小者,如果左指针较小,则从左往右遍历,如果右指针较小,则从右往左遍历,如果遍历到的值比较小者小,则表示可以蓄水:较小者-当前值
public int trap(int[] height) {
int left = 0, right = height.length - 1, mi = 0, res = 0;
while(left < right) {
//如果左指针较小,从左往右遍历
if(height[left] < height[right]) {
mi = height[left++];
while(left < right && height[left] < mi) {
res += mi - height[left++];
}
}
//如果右指针较小,从右往左遍历
else {
mi = height[right--];
while(left < right && height[right] < mi) {
res += mi - height[right--];
}
}
}
return res;
}
42.Trapping Rain Water---dp,stack,两指针的更多相关文章
- 42. Trapping Rain Water [dp][stack]
description: Given n non-negative integers representing an elevation map where the width of each bar ...
- LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))
LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...
- 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 11. Container With Most Water 、42. Trapping Rain Water 、238. Product of Array Except Self 、407. Trapping Rain Water II
11. Container With Most Water https://www.cnblogs.com/grandyang/p/4455109.html 用双指针向中间滑动,较小的高度就作为当前情 ...
- LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...
- [Leetcode][Python]42: Trapping Rain Water
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...
- 刷题42. Trapping Rain Water
一.题目说明 题目是42. Trapping Rain Water,翻译起来就是"接雨水".给n个非负正数代表高度,每个正数宽度为1,让计算能多少雨水.题目难度是Hard 二.我的 ...
- [LeetCode] 42. 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(凹槽的雨水) 解题思路和方法
Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...
随机推荐
- 51nod 1624 取余最短路(set)
题意: 佳佳有一个n*m的带权矩阵,她想从(1,1)出发走到(n,m)且只能往右往下移动,她能得到的娱乐值为所经过的位置的权的总和. 有一天,她被下了恶毒的诅咒,这个诅咒的作用是将她的娱乐值变为对p取 ...
- 两个list比较相等元素
1.实现方式 public class list { public static void main(String[] args) { List<String> list1 = new A ...
- 【开发工具IDE】Eclipse相关配置
1. 修改workspace编码为UTF-8 1.1. 修改jsp编码为UTF-8 2. 修改字体 3. 添加系统中的JDK 4. 导入formatter模板 5. 修改maven配置文件 打开文件: ...
- Javascript面向对象三大特性(封装性、继承性、多态性)详解及创建对象的各种方法
Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation).继承(inheritance )和多态(polymorphism ).只不过实现 ...
- 【SYZOJ279】滑稽♂树(树套树)
[SYZOJ279]滑稽♂树(树套树) 题面 SYZOJ CJOJ 题目描述 zzsyz实验楼里面种了一棵滑稽树,只有滑稽之力达到大乘期的oier才能看到.虽然我们看不到,但是还是知道一些信息: 这真 ...
- windows提权基础大全
Not many people talk about serious Windows privilege escalation which is a shame. I think the reason ...
- Linux(五)shell编程基础
一.Linux shell简介 1.shell概述 Shell 是用户与内核进行交互操作的一种接口,目前最流行的 Shell 称为 bash Shell Shell 是一门编程语言& ...
- [HNOI2006]最短母串问题——AC自动机+状压+bfs环形处理
Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,Sn)都是T的子串. 32MB Input 第一行是一个正整数n(n< ...
- TC规则
633人阅读 TC规则涉及到 队列(QUEUE) 分类器(CLASS) 过滤器(FILTER),filter划分的标志位可用U32或iptables的set-mark来实现 ) 一般是" ...
- 手脱ACProtect v1.35(有Stolen Code)
1.载入PEID ACProtect v1.35 -> risco software Inc. & Anticrack Soft 2.载入OD,需要注意的是,异常选项除了[内存访问异常] ...