第八题:
要求改进分治算法,使其复杂度为O(N)。
既然是分治法,一共有logN层,既然要求复杂度为O(N),那显然程序最后的复杂度应该是O(logN)+O(N)。用动态规划的思想,我们需要花O(N)时间建立两个数组,
before[]和after[]。before[i]表示以第i个元素结尾的最大序列和,after[i]表示以第i个元素开始的最大序列和。建完这个表之后,原来分治法中需要O(N)找到Mc的值,
现在只用O(1)即可获得Mc = before[mid]+after[mid+1]。但是,其实只需要建完before数组后遍历before一次即可找到最大值,因为最大值序列要么是0,要么是以某个元素结尾的序列。 所以我觉得这道题答案如果真是我所想的这样,那无疑是很没有意思的。。但的确是分治法,又的确是O(N)复杂度。
代码如下:
封装在一个类中,init()函数O(N)复杂度,完成before与after的赋值。maxsum3复杂度O(logN),总的复杂度为O(N)+O(logN)。
第十题:
函数equal_zero返回最近接0的子向量之和。
如答案所说,思想是用数组sum[i]记录前i个数字之和,这样任何l,u之间数字之和克表示为sum[u]-sum[i-1]。
O(NlogN)对sum排序,然后遍历查找最近接的相邻元素。
class PearlsCh8{
public:
PearlsCh8(int num, float *data){
n = num;
x = data;
before = new int[n];
after = new int[n];
init();
}
void init(){
before[0] = x[0];
for(int i=1;i<n;++i)
before[i] = before[i-1]>0? (before[i-1]+x[i]) : x[i];
after[n-1] = x[n-1];
for(int i=n-2;i>=0;--i)
after[i] = after[i+1]>0? (after[i+1]+x[i]) : x[i];
}
float maxsum3(int l, int u){
if(l > u)
return 0;
if(l == u)
return max(0,x[l]);
int mid = (l+u)/2;
return max((before[mid]+after[mid+1]),max(maxsum3(l,mid),maxsum3(mid+1,u)));
}
float equal_zero(int l, int u){
int *sum = new int[n+1];
sum[0] = 0;
for(int i=1;i<=n;++i)
sum[i] = sum[i-1] + x[i];
sort(sum,sum+n+1);
float res = x[0];
for(int i=1;i<=n;++i)
res = abs(sum[i]-sum[i-1])<abs(res)?(sum[i]-sum[i-1]):res;
delete[] sum;
return res;
}
private:
int n;
float *x;
int *before;
int *after;
};
int main(){ float x[] = {31,-41,59,26,-53,58,97,-93,-23,84}; PearlsCh8 p(10,x); cout<<p.maxsum3(0,9)<<endl; getchar(); return 0; }
第十三题:
data为M*N的矩阵,算法复杂度为O(M^2*N)。
float maxsum(vector<vector<float> >&data){
int m = data.size();
int n = data[0].size();
vector<vector<float> >sum(n+1,vector<float>(m+1));
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j)
sum[i][j] = sum[i][j-1] + data[j-1][i-1];
}
float res = data[0][0];
for(int i=1; i<=m;++i){
for(int j=i;j<=m;++j){
float end_cur = sum[1][j]-sum[1][i-1];
for(int k=2;k<=n;++k){
end_cur = end_cur>0?(end_cur+sum[k][j]-sum[k][i-1]):(sum[k][j]-sum[k][i-1]);
res = max(res,end_cur);
}
}
}
return res;
}