[leetcode] Trapping Rain Water

来源:互联网 发布:数据地图制作 编辑:程序博客网 时间:2024/05/22 05:11

博客原文:http://blog.csdn.net/doc_sgl/article/details/12307171

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!

方法1:模拟


array [0,1,0,2,1,0,1,3,2,1,2,1]的矩阵如上图所示,是一个3*12的矩阵,然后从矩阵的第一行开始扫描,遇到两个1就加上这两个1之间的水量,只要扫描一遍矩阵就得到水量了,代码如下,小集合通过,大集合memory不够用。

Judge Small: Accepted!

Judge Large: Memory Limit Exceeded

[cpp] view plaincopyprint?
  1. int trap(int A[], int n) {  
  2.         // Note: The Solution object is instantiated only once.  
  3.         if(A==NULL || n<1)return 0;  
  4.         int highest = A[0];  
  5.         for(int i=1;i<n;i++)  
  6.             if(A[i]>highest)highest=A[i];  
  7.         int ** matrix = new int*[highest];  
  8.         for(int i=0;i<highest;i++)  
  9.         {  
  10.             matrix[i]=new int[n];  
  11.             memset(matrix[i],0,sizeof(int)*n);  
  12.         }  
  13.         for(int i = 0; i < n; i++)  
  14.             for(int j = 1; j <= A[i]; j++)  
  15.                 matrix[highest-j][i]=1;  
  16.           
  17.         int water = 0;  
  18.         int left = -1;  
  19.         for(int i = 0; i < highest; i++)  
  20.         {  
  21.             left = -1;  
  22.             for(int j = 0; j < n; j++)  
  23.             {  
  24.                 if(matrix[i][j]==1)  
  25.                 {  
  26.                     if(left==-1)  
  27.                         left = j;  
  28.                     else  
  29.                     {  
  30.                         water += j-left-1;  
  31.                         left = j;  
  32.                     }  
  33.                 }  
  34.             }  
  35.         }  
  36.   
  37.         for(int i=0;i<highest;i++)  
  38.             delete[] matrix[i];  
  39.         delete[] matrix;  
  40.         return water;  
  41.     }  


既然memory不够,就把int矩阵改成bool吧,这样空间就由int的4byte缩小到bool的1 byte,但是还是Memory Limit Exceeded

[cpp] view plaincopyprint?
  1. int trap(int A[], int n) {  
  2.         // Note: The Solution object is instantiated only once.  
  3.         if(A==NULL || n<1)return 0;  
  4.         int highest = A[0];  
  5.         for(int i=1;i<n;i++)  
  6.             if(A[i]>highest)highest=A[i];  
  7.         bool ** matrix = new bool*[highest];  
  8.         for(int i=0;i<highest;i++)  
  9.         {  
  10.             matrix[i]=new bool[n];  
  11.             memset(matrix[i],0,sizeof(bool)*n);  
  12.         }  
  13.         for(int i = 0; i < n; i++)  
  14.             for(int j = 1; j <= A[i]; j++)  
  15.                 matrix[highest-j][i]=1;  
  16.           
  17.         int water = 0;  
  18.         int left = -1;  
  19.         for(int i = 0; i < highest; i++)  
  20.         {  
  21.             left = -1;  
  22.             for(int j = 0; j < n; j++)  
  23.             {  
  24.                 if(matrix[i][j])  
  25.                 {  
  26.                     if(left==-1)  
  27.                         left = j;  
  28.                     else  
  29.                     {  
  30.                         water += j-left-1;  
  31.                         left = j;  
  32.                     }  
  33.                 }  
  34.             }  
  35.         }  
  36.   
  37.         for(int i=0;i<highest;i++)  
  38.             delete[] matrix[i];  
  39.         delete[] matrix;  
  40.         return water;  
  41.     }  


但仔细想想感觉这道题应该是扫一遍就能得到结果的。。。

对某个值A[i]来说,能trapped的最多的water取决于在i之前最高的值leftMostHeight[i]和在i右边的最高的值rightMostHeight[i](均不包含自身)。

如果min(left,right) > A[i],那么在i这个位置上能trapped的water就是min(left,right) – A[i]。

有了这个想法就好办了,第一遍从左到右计算数组leftMostHeight,第二遍从右到左计算rightMostHeight。

时间复杂度是O(n)。

[cpp] view plaincopyprint?
  1. int trap(int A[], int n) {  
  2.         // Note: The Solution object is instantiated only once.  
  3.         if(A==NULL || n<1)return 0;  
  4.           
  5.         int maxheight = 0;  
  6.         vector<int> leftMostHeight(n);  
  7.         for(int i =0; i<n;i++)  
  8.         {  
  9.             leftMostHeight[i]=maxheight;  
  10.             maxheight = maxheight > A[i] ? maxheight : A[i];  
  11.         }  
  12.   
  13.         maxheight = 0;  
  14.         vector<int> rightMostHeight(n);  
  15.         for(int i =n-1;i>=0;i--)  
  16.         {  
  17.             rightMostHeight[i] = maxheight;  
  18.             maxheight = maxheight > A[i] ? maxheight : A[i];  
  19.         }  
  20.   
  21.         int water = 0;  
  22.         for(int i =0; i < n; i++)  
  23.         {  
  24.             int high = min(leftMostHeight[i],rightMostHeight[i])-A[i];  
  25.             if(high>0)  
  26.                 water += high;  
  27.         }  
  28.         return water;  
  29.     }  

0 0
原创粉丝点击