[LeetCode] 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 array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

 

方法一:

时间复杂度 O(n),空间复杂度 O(n)

对于每个柱子,找到其左右两边最高的柱子,该柱子能容纳的面积就是 min(leftMostHeight,rightMostHeight) - height。所以,

1. 从左往右扫描一遍,对于每个柱子,求取左边最大值;

2. 从右往左扫描一遍,对于每个柱子,求最大右值;

3. 再扫描一遍,把每个柱子的面积并累加。

code:

 1 class Solution {
 2     public: 
 3         int trap(int A[], int n) 
 4         {
 5             vector<int> left;
 6             vector<int> right;
 7             left.resize(n);
 8             right.resize(n);
 9 
10             //printArray(A, n);
11 
12             left[0] == 0;
13             right[n-1] == 0;
14             
15             // get the left's max 
16             for(int i = 1; i< n;i++)
17             {
18                 left[i] = max(left[i-1], A[i-1]);
19             }
20             //printVector(left);
21 
22             // get the right's max 
23             for(int i = n-2; i>=0;i--)
24             {
25                 right[i] = max(right[i+1], A[i+1]);
26             }
27             //printVector(right);
28 
29             // clac the trap water
30             int sum =0;
31             int height = 0;
32             for(int i = 0; i< n;i++)
33             {
34                 height = min(left[i], right[i]);
35                 if(height > A[i])
36                     sum += height - A[i];
37             }
38             return sum;
39         }
40 };

方法二:

时间复杂度 O(n),空间复杂度 O(1)

1. 扫描一遍,找到最高的柱子,这个柱子将数组分为两半;

2. 处理左边一半;

3. 处理右边一半。

 1 class Solution {
 2     public:
 3         int trap(int A[], int n) {
 4             int max = 0;  
 5             for(int i = 0; i < n; i++)
 6                 if (A[i] > A[max]) max = i;
 7             int water = 0;
 8             int left_max_height = 0;
 9             // calc the left_max_height, at the same time update water
10             for (int i = 0; i < max; i++)
11                 if (A[i] > left_max_height) 
12                     left_max_height = A[i];
13                 else 
14                     water += left_max_height - A[i];
15             int right_max_height = 0;
16             // calc the right_max_height, at the same time update water
17             for (int i = n - 1; i > max; i--)
18                 if (A[i] > right_max_height) 
19                     right_max_height = A[i];
20                 else 
21                     water +=  right_max_height - A[i];
22             return water;
23         }   
24 };

 

方法3:

// LeetCode, Trapping Rain Water
// 用一个栈辅助,小于栈顶的元素压入,大于等于栈顶就把栈里所有小于或
// 等于当前值的元素全部出栈处理掉,计算面积,最后把当前元素入栈
// 时间复杂度 O(n),空间复杂度 O(n)
可以用std::pair 代替 struct Node结构
 
 1 struct Node
 2 {
 3     int val;
 4     int index;
 5     Node(){}
 6     Node(int v, int idx):val(v), index(idx){}
 7 };
 8 
 9 class Solution {
10     public:
11         int trap(int A[], int n) {
12             stack<Node> s;
13             int sum = 0;
14             for(int i = 0; i < n; i++)
15             {
16                 int height = 0;
17         // 将栈里比当前元素矮或等高的元素全部处理掉
18                 while(!s.empty())
19                 {
20                     Node node = s.top();
21             // 碰到了比当前元素高的,先计算面积,如{4,3,2},再跳出while循环, 将当前元素压栈
22                     if (A[i] < node.val ) // A[] = {4, 2,3}, calc sum
23                     {
24                         int width = i - node.index - 1;
25                         sum += A[i] * width - height * width;
26                         break;
27                     }
28                     else
29                     {
30             // node.val, height, a[i] 三者夹成的凹陷
31                         int width = i - node.index - 1;
32                         sum += node.val * width - height * width;
33                         height = node.val;// update height
34                 // 弹出栈顶,因为该元素处理完了,不再需要了
35                         s.pop();
36                     }
37                 }
38         // 所有元素都要入栈
39                 s.push(Node(A[i], i));
40             }
41 
42             return sum;
43         }
44 };

 

posted @ 2014-06-26 14:36  穆穆兔兔  阅读(187)  评论(0编辑  收藏  举报