最大子列和问题


1
int MaxSubseqSum(int *a,int n) 2 { 3 int ThisSum,MaxSum =0; 4 int i,j,k; 5 for(i=0;i<n;i++) 6 { 7 for(j=i;j<n;j++) 8 { 9 ThisSum=0; 10 for(k=i;k<=j;k++) 11 { 12 13 ThisSum +=a[k]; 14 15 } 16 if(ThisSum>MaxSum) 17 { 18 MaxSum=ThisSum; 19 } 20 } 21 } 22 return MaxSum; 23 }
 1 int MaxSubseqSum(int *a,int n)
 2 {
 3     int ThisSum,MaxSum =0;
 4     int i,j;
 5     for(i=0;i<n;i++)
 6     {
 7         for(j=i;j<n;j++)
 8         {
 9             ThisSum=0;
10             
11             ThisSum +=a[j];
12                 
13             
14             if(ThisSum>MaxSum)
15             {
16                 MaxSum=ThisSum;
17             }
18         }
19     }
20     return MaxSum;
21 }

第一种方法与第二种相比多此一举。第一种时间复杂度为O(n3),第二种时间复杂度O(n2).

 

2.分而治之

 1 #include<stdio.h>
 2 #define maxsize 100000
 3 int max3 (int a,int b,int c)/* 返回3个整数中的最大值 */
 4 {
 5     if(a>=b&&a>=c)
 6     {
 7         return a;
 8     }
 9     else if(b>=a&&b>=c)
10     {
11         return b;
12     }
13     else
14     {
15         return c;
16     }
17 }
18 
19 int MaxSubseqSum(int a[],int left,int right )
20 {
21     
22     int count;
23     int rightsum=0,leftsum=0,thatsum=0,thissum=0;
24     
25     int maxleftsum=0,maxrightsum=0;
26     if(right-left==1)/* 递归的终止条件,子列只有1个数字 */
27     {
28         if(a[left]>0)
29             return a[left];
30         else
31             return 0;
32             
33     }
34     /* 下面是"分"的过程 */
35     int mid=(left+right)/2;
36     /* 递归求得两边子列的最大和 */
37     maxleftsum = MaxSubseqSum(a,left,mid);
38     maxrightsum = MaxSubseqSum(a,mid,right);
39     /* 下面求跨分界线的最大子列和 */
40     for(count=mid-1;count>=left;count--)
41     {
42         thissum+=a[count];
43         if(thissum>leftsum)
44         {
45             leftsum=thissum;
46         }
47     }
48     for(count=mid;count<right;count++)
49     {
50         thatsum+=a[count];
51         if(thatsum>rightsum)
52         {
53             rightsum=thatsum;
54         }
55     }
56     
57     
58     return max3(maxleftsum,maxrightsum,leftsum+rightsum);
59     
60     
61 }
62 int main ()
63 {
64     int len,count;
65     int a[maxsize]={0};
66     scanf("%d",&len);
67     
68     for(count=0;count<len;count++)
69     {
70         scanf("%d",&a[count]);
71     }
72     
73     printf("%d",MaxSubseqSum(a,0,len));
74     return 0;
75 }    

时间复杂度:在递归时其实采用了二分法,时间复杂度为logN,在求跨越边界的最大和时,时间复杂度为N。所以总时间复杂度为O(NlogN).

 

3.在线处理

 1 int MaxSubseqSum(int A[],int N)
 2 {
 3     int ThisSum, MaxSum;
 4     int i;
 5     ThisSum = MaxSum =0;
 6     for(i=0;i<N;i++)
 7     {
 8         ThisSum += A[i];
 9         if(ThisSum > MaxSum)
10             MaxSum = ThisSum;
11         else if(ThisSum < 0)/*如果当前子列和为负*/
12 
13             ThisSum = 0;/*则不可能使后面的部分和增大,抛弃之*/
14     }
15     return MaxSum;
16 }

时间复杂度为O(N).

posted @ 2019-03-02 10:32  qa553415322  阅读(203)  评论(0编辑  收藏  举报