您的位置:首页 > 其它

最大和子数组与最大积子数组(Largest Sum Contiguous Subarray & Maximum Product Subarray)

2014-10-16 13:25 465 查看
在一个数组中找出最大和的子数组(Largest Sum Contiguous subarray),这个问题第一次提出是在1977年ulf-grenander提出的。详见:http://en.wikipedia.org/wiki/Maximum_subarray_problem

初次见到这个题目时,除了暴力破解我没有其他思路。但是google了一下,找到了一个时间复杂度O(n)空间复杂度O(1)的算法:

int Solution::maxSum(int a[], int n)
{
    int max=0;
    int tmax=0;
    for(int i=0;i<n;i++)
    {
        tmax=tmax+a[i];
        if(tmax<0)
        {
            tmax=0;

        }
        max=max>tmax?max:tmax;

    }
    return max;
}


这个经典算法可以稍微优化一下:

int Solution::maxSum2(int a[], int n)
{
    int max=0;
    int tmax=0;
    for(int i=0;i<n;i++)
    {
        tmax+=a[i];
        if(tmax<0)
        {
            tmax=0;
        }
        else
        {
            // do not compare for all element. compare only
            // when tmax>0
            max=max>tmax?max:tmax;
        }
    }
    return max;
}


但是我们仔细分析代码发现,上面的算法对于数组中元素都是负数的情况下不适用。下面这种实现可以解决这个问题:

int Solution::maxSum3(int a[], int n)
{
    int max=a[0],tmax=a[0];
    for(int i=1;i<n;i++)
    {
        tmax=(tmax+a[i])>a[i]?(tmax+a[i]):a[i];
        max=max>tmax?max:tmax;
    }
    return max;
}


与Largest Sum Contiguous Subarray问题类似,有这么一个问题,Maximum Product Subarray,唯一区别是sum变product(积)。

这个问题我同样只会实现暴力破解,时间复杂度为O(n^2):

int Solution::maxProduct(int a[],int n)
{
    int max=a[0];
    for(int i=0;i<n;i++)
    {
        int temp=a[i];
        int tmax=temp;
        // max=tmax;
        for(int j=i+1;j<n;j++)
        {
            temp*=a[j];
            tmax=temp>tmax?temp:tmax;
        }
        max=max>tmax?max:tmax;

    }
    return max;
}


经过google,看了大神们的实现方法,吸收精华,时间复杂度为O(n)的算法:

int Solution::maxProdect2(int a[], int n)
{
    int max=1,tmax=1,tmin=1;
    for(int i=0;i<n;i++)
    {
        // if a[i]>0,update tmax,update tmin only tmin is negtive
        if(a[i]>0)
        {
            tmax=tmax*a[i];
            tmin=tmin*a[i]<1?tmin*a[i]:1;
        }
        else if(a[i]==0)
        {
            tmax=1;
            tmin=1;
        }
        else
        {
            int temp=tmax;
            tmax=tmin*a[i]>1?tmin*a[i]:1;
            tmin=temp*a[i];
        }
        max=max>tmax?max:tmax;
    }
    return max;

}


总结,学习计算机,代码不重要,算法(Algorithm)才是王道!!没有有效的算法,遇到问题码农只能望洋兴叹了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: