题目链接: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,两指针的更多相关文章

  1. 42. Trapping Rain Water [dp][stack]

    description: Given n non-negative integers representing an elevation map where the width of each bar ...

  2. LeetCode 42. Trapping Rain Water 【两种解法】(python排序遍历,C++ STL map存索引,时间复杂度O(nlogn))

    LeetCode 42. Trapping Rain Water Python解法 解题思路: 本思路需找到最高点左右遍历,时间复杂度O(nlogn),以下为向左遍历的过程. 将每一个点的高度和索引存 ...

  3. leetcode#42 Trapping rain water的五种解法详解

    leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...

  4. [array] leetcode - 42. Trapping Rain Water - Hard

    leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...

  5. 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 用双指针向中间滑动,较小的高度就作为当前情 ...

  6. LeetCode - 42. Trapping Rain Water

    42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...

  7. [Leetcode][Python]42: Trapping Rain Water

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...

  8. 刷题42. Trapping Rain Water

    一.题目说明 题目是42. Trapping Rain Water,翻译起来就是"接雨水".给n个非负正数代表高度,每个正数宽度为1,让计算能多少雨水.题目难度是Hard 二.我的 ...

  9. [LeetCode] 42. Trapping Rain Water 收集雨水

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  10. leetCode 42.Trapping Rain Water(凹槽的雨水) 解题思路和方法

    Trapping Rain Water Given n non-negative integers representing an elevation map where the width of e ...

随机推荐

  1. BZOJ 1228 E&G(sg函数+找规律)

    把一对石子堆看出一个子游戏.打出子游戏的sg表找规律.. 这个规律我是一定找不出来的... 对于i,j,如果 (i-1)%pow(2,k+1) < pow(2,k) (j-1)%pow(2,k+ ...

  2. 【bzoj3576】[Hnoi2014]江南乐 博弈论+SG定理+数学

    题目描述 两人进行 $T$ 轮游戏,给定参数 $F$ ,每轮给出 $N$ 堆石子,先手和后手轮流选择石子数大于等于 $F$ 的一堆,将其分成任意(大于1)堆,使得这些堆中石子数最多的和最少的相差不超过 ...

  3. 使用oVal进行Java Bean 验证的注意事项

    如果需要不同条件验证不同的属性的时候,需要使用profiles属性,每个校验注解符中都有.注意:oVal默认是启用所有的profiles,所以在对单独一个profile进行启用的时候,需要先disab ...

  4. 【Aizu2292】Common Palindromes(回文树)

    [Aizu2292]Common Palindromes(回文树) 题面 Vjudge 神TMD日语 翻译: 给定两个字符串\(S,T\),询问\((i,j,k,l)\)这样的四元组个数 满足\(S[ ...

  5. 洛谷 P4219 [BJOI2014]大融合 解题报告

    P4219 [BJOI2014]大融合 题目描述 小强要在\(N\)个孤立的星球上建立起一套通信系统.这套通信系统就是连接\(N\)个点的一个树. 这个树的边是一条一条添加上去的.在某个时刻,一条边的 ...

  6. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  7. 【数论】数论进阶-Preknowledge

    数论进阶-Preknowledge 参考资料:洛谷网校2018夏季省选基础班SX-3数论进阶课程及课件 一.整除与取整除法 1.1 定义 1.整除 \(\forall~x,y~\in~Z^+,\) 若 ...

  8. [POI2014] KUR-Couriers (主席树)

    [POI2014]KUR-Couriers 题目描述 Byteasar works for the BAJ company, which sells computer games. The BAJ c ...

  9. python中如何优雅使用import

    http://note.youdao.com/noteshare?id=c55be6a8565f5eb586aa52244b3af010

  10. iOS APNs实战分享

    序言: 因为App的功能需要,最近一直在调研苹果的APNs推送,开始时觉得超麻烦,现在感觉还是比较easy,“难者不会,会者不难”,自己踩过了这么多的坑终于会了,不出来吐槽(装X)一下对不起自己,23 ...