class Solution {
public:
int query_V(int *p,int a,int b){//操作1> 求任意两柱子中间的面积
int res=0;
for(int i=a+1;i<b;i++) res+=*(p+i);
return min( *(p+a),*(p+b) )*(b-a-1)-res;
}
int trap(vector<int>& height) {
int n=height.size();if(n==1) return 0;//特判
int left=0,ans=0;height.push_back(0);
while(left<n && height[left]==0 ) left++;//前置0存不住水,直接跳过
while(left<n ) {
int right,minx_id=n;
for(right=left+1;right<n;right++)
if(height[right]>=height[left]){//情况1
ans+=query_V( &height[0],left,right);
break;
}else if(height[right]>=height[minx_id]) minx_id=right;//情况2
if(right<n ) left=right;//有大于自己的right
else if(height[minx_id]!=0){//没有比自己大的,就去选最好的备胎
ans+=query_V(&height[0],left,minx_id);
left=minx_id;
}else left++;
}
return ans;
}
};
显然…这暴力方法是我自己造得,感觉很蠢,而且这种坐标轴上的题,总是会有很巧妙的方法,所以看了一眼人家的做法。
const int N=2e4+10;
#define h height
#define n height.size()
class Solution {
public:
int trap(vector<int>& height) {
int ans=0,r[N],l[N];l[0]=h[0];r[n-1]=h[n-1];
for(int i=n-2;i>=0;i--) r[i]=max(r[i+1],h[i]);
for(int i=1;i<n;i++) l[i]=max(l[i-1],h[i]);
for(int i=0;i<n;i++) ans+=max(min(l[i],r[i])-h[i],0);
return ans;
}
};
巧妙!