给定n个数(有正有负数),怎样求解最小的连续正子序列之和

感觉很多答案都是求最大子段和的。lz的要求是:1:连续的一段子序列 。2:该子序列之和必须是正的 。3:求所有满足1,2条件中的最小的。这样的话,n*log(n)还是容易做到的,记录前缀累加和,然后排序,检查相邻的两项是否能够组成子序列,可以的话就记录该值D,记录最小的D就是结果。
■网友
谢邀。FT...如果楼主的意思是子序列中的元素都要是正的...那就当我以下没说吧...==============================================================抛砖引玉。呃,想了一下,没有找到类似最大子序列的O(n)的做法,希望楼上能详细指出供学习。但是有一个很简单的O(nlogn)的办法。首先,任何一个子序列的和,都可以表示成sum - sum,其中sum表示的是从1...i的序列和。那么对于任意一个R,我们只需要找到一个刚刚比它小的sum,(i\u0026lt;R)这样,两者相减,就是以R为结尾的最小正子序列的和了。然后所有的{R|1\u0026lt;=R\u0026lt;=N}取个最小的就是答案了。而找到刚刚比sum小的sum,我们可以用一颗平衡树来搞定(如果要省力的话,具体实现的时候用STL这类的标准模版就行了),这样我们可以对于每一个R,在logn时间内找到sum,(i\u0026lt;=R).
■网友
minSum=INT_MAX;sum=0;for number in list { if (number \u0026lt;= 0) { if (sum!=0 \u0026amp;\u0026amp; sum \u0026lt; minSum) { minSum=sum; sum=0; } } else { sum+=number; }}if (INT_MAX == minSum) { return error;} else { return minSum;}
■网友
我才学完数据结构与算法分析C++描述_Mark.Allen.Weiss 第二章(算法分析),课后习题正好有这题,抛砖引玉一下:运用O(N平方)很好解://简单粗暴 双重循环int result_2(const vector\u0026lt;int\u0026gt;\u0026amp;v){ int maxSum=0; for(int i=0;i!=v.size();++i){ int temp=0; for(int j=i;j!=v.size();++j){ temp+=v ; if(temp\u0026gt;0 \u0026amp;\u0026amp; ((temp\u0026lt;maxSum) || maxSum\u0026lt;=0)) maxSum=temp; } } return maxSum;}但是到O(Nlog(N) )便卡壳了,无法做到完美,代码如下:int min_2(int a,int b){ //返回两个值的最小 正 值 if(a\u0026lt;=0\u0026amp;\u0026amp;b\u0026gt;0)return b; if(a\u0026gt;0\u0026amp;\u0026amp;b\u0026lt;=0)return a; return min(a,b);}int min_4(int a,int b,int c,int d){ //返回四个值的最小 正 值 return min_2 (min_2 (min_2(a,b), c) , d);}//分治 divide and conquer 但此例效果不好,也许不是所有例子都适合分治int min_positive_sum (const vector\u0026lt;int\u0026gt;\u0026amp;v,int l,int r) { if(l==r)return v; //base case int mid=(l+r)/2; int left_result=min_positive_sum(v,l,mid); int right_result=min_positive_sum(v,mid+1,r); //包含 两个 中间元素的最小正子序列和//这里会有些小问题,{100,-4,3,4,-2,100} 结果只能得到2,主要是顺序问题无法搞通,此例 中需要围绕中间的3和4进行左右扩展,而且是左右不一定相同扩展速度的 int temp_union_1=v+v , temp_union_2=temp_union_1,union_sum_1=temp_union_1 , union_sum_2=union_sum_1; for (int i=mid-1;i\u0026gt;=l;--i) { temp_union_1+=v; if(temp_union_1\u0026gt;0 \u0026amp;\u0026amp; ((temp_union_1\u0026lt;union_sum_1) || union_sum_1\u0026lt;=0)) union_sum_1=temp_union_1; } for(int i=mid+2;i\u0026lt;=r;++i) { temp_union_1+=v; if(temp_union_1\u0026gt;0 \u0026amp;\u0026amp; ((temp_union_1\u0026lt;union_sum_1) || union_sum_1\u0026lt;=0)) union_sum_1=temp_union_1; temp_union_2+=v; if(temp_union_2\u0026gt;0 \u0026amp;\u0026amp; ((temp_union_2\u0026lt;union_sum_2) || union_sum_2\u0026lt;=0)) union_sum_2=temp_union_2;} for(int i=mid-1;i\u0026gt;=l;--i) { temp_union_2+=v; if(temp_union_2\u0026gt;0 \u0026amp;\u0026amp; ((temp_union_2\u0026lt;union_sum_2) || union_sum_2\u0026lt;=0)) union_sum_2=temp_union_2;} return min_4(union_sum_1,union_sum_2, left_result, right_result); //四者中最小正值}int result(const vector\u0026lt;int\u0026gt;\u0026amp;v){ return min_positive_sum(v,0,v.size()-1);}


推荐阅读