class Solution { public: int trap(vector<int>& height) { int n = height.size(); //小于等于两个是蓄不住水的。 if(n <= 2) return 0; int ans = 0; int Max = -1; int k = -1; //找到至高点。 for(int i = 0; i < n; i++){ //先减去柱子本身高度 ans -= height[i]; if(Max < height[i]) Max = height[i], k = i; } //加上整个图的面积 ans += n*Max; //从前到最高点,每次减去从开始到每个更高柱子高度的面积。 int cur = height[0]; int i = 1; while(i <= k){ //i为从开始到当前柱子距离。height[i]-cur为高度差。 if(height[i] > cur) ans -= i * (height[i]-cur),cur = height[i]; i++; } cur = height[n-1]; i = height.size()-2; while(i>=k){ //i最后到当前柱子的距离。height[i]-cur为高度差。 if(height[i] > cur) ans -= (n-i-1) * (height[i]-cur),cur = height[i]; i--; } return ans; } };
class Solution { public: int trap(vector<int>& height) { int n = height.size(); stack<int> s; int ans = 0; for(int i = 0; i < n; i++){ //找每个元素右边最近的大于他的值。//单调递减栈 while(s.size() && height[i] > height[s.top()]){ int top = s.top(); s.pop(); if(s.empty())break; //由于维持的是单调递减栈,所以当前栈顶是目前已知的最小一个元素,将栈顶取出,而新的栈顶元素与新发现的比它大的元素,一定能就组成边界,使得以目前最小元素为底,至左右边界中小的那一个,可以接到雨水。形象点就是一层一层的接。 int dis = i-s.top()-1; ans += dis * (min(height[i],height[s.top()])-height[top]); } s.push(i); } return ans; } };