• [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 };
  • 相关阅读:
    AcWing 286. 选课
    背包问题极小值空间至少是j
    Logo在线公式编辑转图片
    AcWing 1055. 股票买卖 II
    枚举一个集合的所有有效子集
    CF580D Kefa and Dishes [洛谷]
    AcWing 1282. 搜索关键词
    背包问题最大值空间恰好是j
    多叉树转二叉树有依赖的背包问题解法
    Thinkpad T14重装Win10后不见无线网络问题的解决
  • 原文地址:https://www.cnblogs.com/diegodu/p/3810060.html
Copyright © 2020-2023  润新知