No.42 Trapping Rain Water

 1 class Solution
 2 {
 3 public:
 4     int trap(vector<int> &height)
 5     {/*
 6         雨水覆盖问题:
 7         每一个bar能承受的水量为:它左侧所有中最高的和右侧所有中最高的中取最小值作为一个瓶颈[否则也留不住],
 8                                  若该值大于当前bar的高度,其差值即为所求
 9         累加所有bar能承受的水量即为所求
10     法三:【左右两个指针】
11         找到最高的位置,将数组分为两部分:
12         对左侧数据,因为右边已经有了最高值,所以,类似法一,找到其左侧最高值[为瓶颈],再与当前bar的高度比较,若低于瓶颈,累加其差值;
13     对右侧数据,因为左边已经有了最高值,所以,找到右侧最高值[为瓶颈],再与当前bar的高度比较,若低于瓶颈,累加其差值
14     时间复杂度:O(n); 空间复杂度:O(1)
15      */
16         int count = height.size();
17         int res=0;
18         if(count < 3)//一个符号引发的错误,不是<=
19             return 0;
20
21         int l = 0;
22         int r = count-1;
23         int min;
24         while(l<r)
25         {
26             min = (height[l]<=height[r] ? height[l] : height[r]);
27             if(height[l] == min)
28             {
29                 l++;
30                 while(l<r && height[l]<min)
31                 {
32                     res += min-height[l];
33                     l++;
34                 }
35             }
36             else
37             {
38                 r--;
39                 while(l<r && height[r] < min)
40                 {
41                     res += min-height[r];
42                     r--;
43                 }
44             }
45
46         }
47         return res;
48     }
49 };

No.42 Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

Tags: Array Stack Two Pointers

每一个bar能承受的水量为:它左侧所有中最高的和右侧所有中最高的中取最小值作为一个瓶颈[否则也留不住],
                   若该值大于当前bar的高度,其差值即为所求
累加所有bar能承受的水量即为所求

思路清晰,一切不是问题

方法一:从左向右扫描,找到当前bar左侧最高的记录下来;

    从右向左扫描,找到当前bar右侧最高的,将其与左侧最高比较,取其小作为瓶颈

    若当前bar的高度低于瓶颈,差值累加得到结果

    时间复杂度:O(n); 空间复杂度:O(n)

 1 #include "stdafx.h"
 2 #include <vector>
 3 #include <iostream>
 4 using namespace std;
 5
 6 class Solution
 7 {
 8 public:
 9     int trap(vector<int> &height)
10     {/*
11         雨水覆盖问题:
12         每一个bar能承受的水量为:它左侧所有中最高的和右侧所有中最高的中取最小值作为一个瓶颈[否则也留不住],
13                                  若该值大于当前bar的高度,其差值即为所求
14         累加所有bar能承受的水量即为所求
15      */
16         int count = height.size();
17         int res=0;
18         if(count < 3)//一个符号引发的错误,不是<=
19             return 0;
20         int *container = new int[count];//辅助数组
21         int max=0;//记录当前出现的最大值
22         for(int i=0; i<count; i++)
23         {//计算i左侧的最大值
24             container[i] = max;
25             max = (height[i]>max ? height[i] : max);//更新max
26         }
27         max = 0;
28         for(int i=count-1; i>=0; i--)
29         {//计算i右侧的最大值
30             container[i] = (max<container[i] ? max : container[i]);
31             max = (height[i]>max ? height[i] : max);//更新max
32             //同时统计总容量
33             res += (container[i]>height[i] ? (container[i]-height[i]) : 0 );
34         }
35         delete[] container;//别忘
36         return res;
37     }
38 };
39
40 int main()
41 {
42     Solution sol;
43 //    int data[] = {0,1,0,2,1,0,1,3,2,1,2,};
44     int data[] = {2,0,2};
45     vector<int> test(data,data+sizeof(data)/sizeof(int));
46
47     cout << sol.trap(test)<<endl;
48
49 }

方法二:找到最高的位置,将数组分为两部分:

    对左侧数据,因为右边已经有了最高值,所以,类似法一,找到其左侧最高值【为瓶颈】(肯定小于右侧最高点),再与当前bar的高度比较,若低于瓶颈,累加其差值;

    对右侧数据,因为左边已经有了最高值,所以,找到右侧最高值【作为瓶颈】,再与当前bar的高度比较,若低于瓶颈,累加其差值

    时间复杂度:O(n); 空间复杂度:O(1)

 1 class Solution
 2 {
 3 public:
 4     int trap(vector<int> &height)
 5     {/*
 6         雨水覆盖问题:
 7         每一个bar能承受的水量为:它左侧所有中最高的和右侧所有中最高的中取最小值作为一个瓶颈[否则也留不住],
 8                                  若该值大于当前bar的高度,其差值即为所求
 9         累加所有bar能承受的水量即为所求
10     法三:【左右两个指针】
11         找到最高的位置,将数组分为两部分:
12         对左侧数据,因为右边已经有了最高值,所以,类似法一,找到其左侧最高值[为瓶颈],再与当前bar的高度比较,若低于瓶颈,累加其差值;
13     对右侧数据,因为左边已经有了最高值,所以,找到右侧最高值[为瓶颈],再与当前bar的高度比较,若低于瓶颈,累加其差值
14     时间复杂度:O(n); 空间复杂度:O(1)
15      */
16         int count = height.size();
17         int res=0;
18         if(count < 3)//一个符号引发的错误,不是<=
19             return 0;
20
21         int maxIndex = 0;
22         //找到最高点的位置,将数组一分为二
23         for(int i=0 ; i<count; i++)
24         {
25             if(height[i] > height[maxIndex])
26                 maxIndex = i;
27         }
28         int max=0;//记录左侧/右侧当前最大值
29         for(int i=0; i<maxIndex; i++)
30         {
31             res += ((height[i] < max ? max-height[i] : 0));//注意细节!!!
32             max = (height[i]>max ? height[i] : max );
33         }
34
35         max = 0;
36         for(int i=count-1; i>maxIndex; i--)
37         {
38             res += ((height[i] < max ? max - height[i] : 0));
39             max = (height[i]>max ? height[i] : max );
40         }
41         return res;
42     }
43 };

法三: 两指针法【理解上,还是有点问题】

  用两个指针从两端往中间扫瞄,

  在当前窗口下:

    如果哪一侧的高度是小的,那么从这里开始继续扫;

    如果比它还小的,肯定装水的瓶颈就是它了,可以把装水量加入结果;

    如果遇到比它大的,立即停止,重新判断左右窗口的大小情况,重复上面的步骤。这里能作为停下来判断的窗口,说明肯定比前面的大了,所以目前肯定装不了水(不然前面会直接扫过去)。

    这样当左右窗口相遇时,就可以结束了,因为每个元素的装水量都已经记录过了。

参考:http://blog.csdn.net/linhuanmars/article/details/20888505

时间: 2024-10-01 07:09:42

No.42 Trapping Rain Water的相关文章

42. Trapping Rain Water(js)

42. Trapping Rain Water Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1].

刷题42. Trapping Rain Water

一.题目说明 题目是42. Trapping Rain Water,翻译起来就是"接雨水".给n个非负正数代表高度,每个正数宽度为1,让计算能多少雨水.题目难度是Hard 二.我的解法 这个题目是找"坑",然后计算里面可以存的"雨".总共提交了5次,前面几次都是边界错误. 代码如下: #include<iostream> #include<vector> using namespace std; class Solutio

[Leetcode][Python]42: Trapping Rain Water

# -*- coding: utf8 -*-'''__author__ = '[email protected]' 42: Trapping Rain Waterhttps://oj.leetcode.com/problems/trapping-rain-water/ Given n non-negative integers representing an elevation map where the width of each bar is 1,compute how much water

11 Container With Most Water 42.Trapping Rain Water

11 和 42 本质上都是木桶原理: 11 如何才能存最多的水? 假设 a[left] < a[right] ,    total = a[left] *(right-left) ,  那么 right -1, right-2 位置 都比 total 小, 此时就没必要move right 了, 因为所有的right -x 都比 right 小. 此时只需要move left 指针, 继续找最大value. code 很简单: public int maxArea(int[] height) {

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

Trapping Rain Water Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The above elevation map

42. Trapping Rain Water

题目: Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The above elevation map is represented

42. Trapping Rain Water *HARD*

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The above elevation map is represented by a

[leedcode 42] Trapping Rain Water

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The above elevation map is represented by a

【一天一道LeetCode】#42. Trapping Rain Water

一天一道LeetCode系列 (一)题目 Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much >water it is able to trap after raining. For example, Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6. The above elevation m