[leetcode] Trapping Rain Water
思路1:
使用递归的方法,直接考虑该问题,对于任意的这样一组数据,如果要求能容的最多的水,有一点是确定的:如果我们能找到数组里面的最大的两个数,那个这两个数之间能容的最多的水是确定的。设数据为An,而最大的两个数依次为ai,aj, 且i>j, 则trap(An) = trap(A[0:i]) + trap(A[i,j]) + trap(A[j,n]), 此算法的时间复杂度为nlgn, accepted的代码如下:
1 class Solution { 2 public: 3 int cal_trap(vector<int>&height, int left, int right) { 4 int result = 0; 5 int max_height = std::min(height[left], height[right]); 6 for(int i=left+1; i<right; i++) { 7 result += (max_height-height[i]); 8 } 9 return result; 10 } 11 int cur_trap(vector<int>& height, int left, int right){ 12 if (right-left <= 1) return 0; 13 int max_h = left, next_h = left; 14 int max_h_value = -1, next_h_value = -1; 15 for(int i=left; i<=right;i++) { 16 if(height[i] > max_h_value) { 17 next_h_value = max_h_value; 18 next_h = max_h; 19 max_h = i; 20 max_h_value = height[i]; 21 } else if(height[i] > next_h_value){ 22 next_h = i; 23 next_h_value = height[i]; 24 } 25 } 26 int new_left = 0, new_right = 0; 27 if (max_h > next_h) { 28 new_left = next_h; 29 new_right = max_h; 30 } else { 31 new_left = max_h; 32 new_right = next_h; 33 } 34 return cal_trap(height, new_left, new_right) + cur_trap(height, left, new_left) 35 + cur_trap(height, new_right, right); 36 } 37 int trap(vector<int>& height) { 38 return cur_trap(height, 0, height.size()-1); 39 } 40 };
思路2:
即是网上看到的时间复杂度为n的方法,利用stack结构,其原理是利用stack中只保存逐步递减的高度,然后,遇到比stack.top()的原理,则对结果进行加(相当于加水到某一高度),直接上代码:
1 class Solution { 2 public: 3 4 int trap(vector<int>& height) { 5 size_t s = height.size(); 6 if (s<3) return 0; 7 int result = 0, bottom = 0; 8 stack<int> slop; 9 for (size_t i=0;i<height.size();i++) { 10 while(!slop.empty() && height[i] >=height[slop.top()]) { 11 bottom = height[slop.top()]; 12 int cal_loc = slop.top(); 13 slop.pop(); 14 if(!slop.empty()) { 15 result += (i-slop.top()-1) * (min(height[i], height[slop.top()])-bottom); 16 } 17 } 18 slop.push(i); 19 } 20 return result; 21 } 22 };
思路3:
原理是对于某一位置,其上能容的最大的水是由其左边及右边的最高值确定的,即如果对ai, 其左边最高的值为al, 其右边最高的值为ar, 则在位置i, 其最多能容纳min(al, ar)-ai, 代码如下:
1 class Solution { 2 public: 3 4 int trap(vector<int>& height) { 5 size_t s = height.size(); 6 if(s<3) return 0; 7 vector<int> left_max(s, 0); 8 vector<int> right_max(s, 0); 9 int max_left_value=0, max_right_value = 0; 10 for(size_t i=0;i<s;i++) { 11 if (height[i]>max_left_value) { 12 max_left_value = height[i]; 13 } 14 if (height[s-1-i] > max_right_value) { 15 max_right_value = height[s-1-i]; 16 } 17 left_max[i] = max_left_value; 18 right_max[s-1-i] = max_right_value; 19 } 20 int result = 0; 21 for (size_t i= 0;i<s;i++) { 22 result += std::min(left_max[i], right_max[i]) - height[i]; 23 } 24 return result; 25 } 26 };
浙公网安备 33010602011771号