这种题目的关键就是找到内在逻辑,然后递推下去。我的思路是,先找到最高的点,再依次向左右找次高的点,计算水容量,然后不断递归找次高点,直到边界位置。虽然实现了,结果十分繁琐!!
struct Rank
{
int height;
int rank1;
};
static bool cmp(Rank a,Rank b)//不加static好像会报错
{
return a.height>b.height;
}
int cal(vector<int>& H,int a,int b)
{
int sum=0,temp=H[a]<H[b]? H[a]:H[b];
for(int i=a+1;i<=b-1;i++) //曾经此处少了等于号,调试半天
sum+=temp-H[i];
return sum;
}
int seek1(vector<int>& H,vector<Rank> &R,int a,int b,int sum,int c)//传入向量必须+&,向左寻找次高点
{
if(a==0) {sum+=cal(H,a,b);return sum;}
else{
sum+=cal(H,a,b);
int i;
for(i=c;i<R.size();i++)
{
if(R[i].rank1<a) break;
}
return seek1(H,R,R[i].rank1,a,sum,i+1);//此处竟然忘记return
}
}
int seek2(vector<int>& H,vector<Rank> &R,int a,int b,int sum,int c)
{
if(b==H.size()-1) return sum+cal(H,a,b);
else{
sum+=cal(H,a,b);
int i;
for(i=c;i<R.size();i++)
{
if(R[i].rank1>b) break;
}
return seek2(H,R,b,R[i].rank1,sum,i+1);
}
}
int trap(vector<int>& H) {
vector<Rank> R;
if(H.size()==0) return 0;
for(int i=0;i<H.size();i++)
{
Rank temp;
temp.height=H[i];
temp.rank1=i;
R.push_back(temp);
}
sort(R.begin(),R.end(),cmp);
int sum=0;
sum+=seek1(H,R,R[0].rank1,R[0].rank1,0,1);
sum+=seek2(H,R,R[0].rank1,R[0].rank1,0,1);
return sum;
}
然而,简单的思路恰好与我相反,从两边出发(two point),到中间汇合,无需递归,为啥我就没反过来想想呢??
int trap(int A[], int n) {
int left=0; int right=n-1;
int res=0;
int maxleft=0, maxright=0;
while(left<=right){
if(A[left]<=A[right]){
if(A[left]>=maxleft) maxleft=A[left];
else res+=maxleft-A[left];
left++;
}
else{
if(A[right]>=maxright) maxright= A[right];
else res+=maxright-A[right];
right--;
}
}
return res;
}