题目:最大子列和
问题描述:给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
算法描述:
采用分治的方法,将序列分成左右两段,再计算出左段的最大子列和,右端的最大字列和,还有跨越两边的最大子列和,最后将三者进行比较得出结果,需要注意的是全为负数的情况应该输出0.
int max(int* a,int left,int right) { if(left==right) { if(a[left]>0) return a[left]; else return 0; } int mid = (left+right)/2; int leftmax = max(a,left,mid); int rightmamx = max(a,mid+1,right); int lmax=0,lsum=0; for(int i=mid;i>=left;i--) { lsum += a[i]; if(lsum > lmax) lmax = lsum; } int rmax=0,rsum=0; for(int i=mid+1;i<=right;i++) { rsum += a[i]; if(rsum > rmax) rmax = rsum; } if(rmax > lmax && rmax > (rmax+lmax)) return rmax; if(lmax > rmax && lmax > (rmax+lmax)) return lmax; if(rmax+lmax > lmax && lmax+rmax > rmax) return lmax+rmax; }
算法时间及空间复杂度分析:
每次都将问题分为两个子问题,每个子问题中又有时间复杂度为O(n/2)的操作,还有跨越边界的问题O(n),
所以时间复杂度为T(n)=2T(n/2)+O(n)=O(nlogn).
空间复杂度则为S(n)=O(n),因为用到的只是一个一维的数组。
心得体会:
这个问题难了我非常久的时间,我知道要把问题分成规模小的问题,但是一开始并没有处理好跨越边界的问题,导致一直出错,这个问题让我对分治法有了十分深刻的理解和印象,一开始都是递归的结束条件,然后则是不断的分解成小问题。