accept?真是一阵惊喜,没想到这方法能通过,而且反应了有一会儿。先回顾一下前面的相关的题目http://oj.leetcode.com/problems/container-with-most-water/ http://blog.youkuaiyun.com/littlestream9527/article/details/17174075 这题当然不一样了,首先每个元素本身都要占据面积的,其次不是求最值,没有趋向性;像这种82503502503509,两个高墙之间夹多个隔槽的怎么分呢,最多的水肯定是在两个高槽的位置,关键是找中间的墙占多大的面积,一想有点复杂我就从另一个角度入手了。我是这样想的:一层一层地算面积,先算高度最小的那层的面积,再算上一层高度的(注意,上一层高度和下一层高度没什么关系,要把下一层的高度减去),这样一直到最大的高度(其实到的二大的高度就行了)。这复杂度其实不低,O(n)*高度的数量。好歹下面的代码通过了。可能会有更好的吧,明天再说。
int trap(int A[], int n) {
set<int> st;
for (int i=0;i<n;i++)
{
st.insert(A[i]);
}
int sum = 0;
set<int>::iterator iter = st.begin();
int height=0,lastheight=0;
while(iter!=st.end())
{
height = *iter;// - lastheight;
int i=0;
while(i<n&&A[i]<height)//looking for the first higher than layer
i++;
while(i<n)
{
while(i<n&&A[i]>=height)// looking for the first lower than layer
i++;
--i;
int j = i + 1;
while(j<n&&A[j]<height)// looking for the first higher than layer
j++;
if (j<n)
{
sum += (j-i-1)*(height - lastheight);// each time one layer
}
i = j;
}
lastheight = height;
iter++;
}
return sum;
}
第二种方法,自己想的,思想应该是分治思想,首先找最大的两个元素位置,这两个之间的面积可求,然后求左侧剩下的和右侧剩下的,整体和就是所求的解。如下:
int reversive_trap(int *arr,int start,int end)
{
if (start>=end||start + 1==end)
{
return 0;
}
int maxheight = arr[start],secondeheight= 0;
int maxpos = start, secondpos = start+1;
for (int i=start+1;i<=end;i++)
{
if (maxheight<=arr[i])
{
secondeheight = maxheight;
secondpos = maxpos;
maxheight = arr[i];
maxpos = i;
}
else
{
if (secondeheight<arr[i])
{
secondeheight = arr[i];
secondpos = i;
}
}
}
int leftpos = secondpos,rightpos = maxpos;
int height = secondeheight;
if (leftpos > rightpos)
{
leftpos = maxpos;
rightpos = secondpos;
}
int sum=0;
sum = height * (rightpos - leftpos - 1);
for (int j=leftpos+1;j<rightpos;j++)
{
sum -= arr[j];
}
return sum + reversive_trap(arr,start,leftpos) + reversive_trap(arr,rightpos,end);
}
int trap(int A[], int n) {
return reversive_trap(A,0,n-1);
}