相亲大会——求最大子串和



题目:



分析:

思路一:

要求最大的子串和,最简单粗暴的方法就是枚举法,枚举出所有可能的子串并求和,然后逐一比较,得出和最大的子串,用两重循环就可以实现。比如 a[3]={1,-2,3},第一重循环i从0到2,第二重循环j从i+1到2,这样的话,就有以下的情况:
* 1 =1
* 1 -2 =-1
* 1 -2 3 =2
* -2 =-2
* -2 3 =1
* 3 =3
所以最大子串和就是3。


思路二:

思路一的方法可行,但是有些情况可以不用考虑,直接跳过,也就是说有些情况下第二重循环可以提前结束。这样的话可以节省一些时间。当某个时候,子串和是负数时,就可以直接跳出第二重循环了,由于对后面的情况,如果加上一个负数,就一定会比不加要小,所以后面不会是和最大的了。比如上面的例子,当出现1 -2时,和是-1,为负数,那么1 -2 3的情况就可以不考虑了,因为它的和一定会比最后一种情况3要小。同样的,出现-2后,-2 3的情况也可以不考虑,这样就可以简便一些。


思路三:

上面两种方法虽然可行,但都需要两重循环,思路二虽然跳过了一些情况,但还是过于复杂。这里提出第三种方法,如果理解了思路二的简化原理后,理解第三种方法就比较容易了。要求最大的子串和,可以用一个temp来进行累加,如果temp>=0,就把当前的数加入temp,当遇到temp<0时,就让temp等于当前的数。因为当temp>0时,对后面的子串来说,是使和增大,而当temp<0时,对后面的子串来说是使和减小,最大的子串和一定是出现在后面。比如a[5]={1,2,-4,5,6},temp=1,加上2就是3,对2来说是使子串和变大。temp=3,对-4来说,也是使-4变大,所以加上-4.temp=-1,对5来说是使5变小,所以不加,令temp=5,再加上6,就是最大的子串和。如果刚才加上temp=-1,对于5 6这个子串来说,他们的和就变小了。这样一来,就只需要遍历一遍就好了,一重循环就够了,大大降低了时间复杂度。



代码:

思路一:

#include<stdio.h>     

int main()   
{
    int n,a[100000];   
    int i,j;   
    int max,temp;              //max记录最大子串和,temp用于累加
   
    scanf("%d",&n);   
   
    for(i=0;i<n;i++)   
        scanf("%d",&a[i]);   
       
    max=a[0];   
   
    for(i=0;i<n;i++)   
    {      
        temp=a[i];   
        if(temp>max)          //如果temp>max,就用max记录
            max=temp;   
       
        for(j=i+1;j<n;j++)   
        {   
            temp+=a[j];   
            if(temp>max)   
                max=temp;   
        }   
    }   
   
    printf("%d
",max);
   
    return 0;   
 }  

思路二:

#include<stdio.h>  

int main()   
{   
    int n,a[100000];   
    int i,j;   
    int max,temp;                      //max记录最大子串和,temp用于累加
   
    scanf("%d",&n);   
   
    for(i=0;i<n;i++)   
        scanf("%d",&a[i]); 
       
    max=a[0];   
   
    for(i=0;i<n;i++)   
    {      
        temp=a[i];   
        if(temp>max)                    //如果temp>max,就用max记录
            max=temp;   
       
        for(j=i+1;j<n;j++)   
        {   
            temp+=a[j];
            if(temp<=0)            //temp<0,提前结束循环
	            break; 
            if(temp>max)   
                max=temp;   
        }   
    }   
   
    printf("%d
",max); 
  
    return 0;   
 } 

思路三:

#include<stdio.h>

int main()
{
    int n,i,a[100000];
    int temp=0;
    int max=-1001;

    scanf("%d",&n); 

    for(i=0;i<n;i++)
	    scanf("%d",&a[i]);
	
    for(i=0;i<n;i++)
    {
	    if(temp<0)                 //temp<0,等于当前数
		    temp=a[i];
	    else                       //temp>=0,temp继续累加
		    temp+=a[i];
	    if(temp>max)               //如果temp>max,就用max记录
		    max=temp;
    }

    printf("%d
",max);

    return 0;
}


原文地址:https://www.cnblogs.com/jiuweilinghu/p/5931697.html