最大子序列问题

问题定义:对于一包含n个浮点数的向量,求其连续序列的最大值

解法一:枚举法是一种显而易见的做法,其时间复杂度为O(n*n*n)

int MaxSubsequence(int n,int x[])
{
    // insert code here...
    int maxsofar = 0;
    int i = 0;
    int j = 0;
    int k = 0;
    for (i = 0; i < n; i++)
    {
        for (j = i; j < n; j++)
        {
            int sum = 0;
            for (k = i; k < j+1; k++)
            {
                sum += x[k];
                maxsofar = max(maxsofar,sum);
            }
        }
    }
    return maxsofar;

}

这段代发简洁明了,但时间复杂度为立方,运行速度太慢

解法二:在解法一的基础上对其进行优化,总和sum可以由第二循环得出,不需要再嵌套一个循环来计算总和。保存状态避免重复计算。这样使时间复杂度降到了平方。

int MaxSubsequence(int n,int x[])
{
    // insert code here...
    int maxsofar = 0;
    int i = 0;
    int j = 0;
    for (i = 0; i < n; i++)
    {
        int sum = 0;
        for (j = i; j < n; j++)
        {
            sum += x[j];
            maxsofar = max(maxsofar, sum);

        }
    }
    return maxsofar;

}

另外一种类似的算法是对信息进行预处理。数组cumarr的第i个元素为x[0…i]的累加和,所以x[i…j]中各个数的总和可以通过计算cumarr[i]-cumarr[i-1]得到。起事件复杂度也为平法。

int MaxSubsequence(int n,int x[])
{
    // insert code here...
    int maxsofar = 0;
    int i = 0;
    int j = 0;
    int sum = 0;
    int cumarr[] = {0,0,0,0,0,0,0};
    for (i = 0; i < n; i++)
    {
        cumarr[i] = cumarr[i-1] + x[i];
    }
    maxsofar = 0;
    for (i = 0; i < n; i++) {
        for (j = i; j < n; j++) {
            sum = cumarr[j] - cumarr[i-1];
            maxsofar = max(maxsofar,sum);
        }
    }
    return maxsofar;

}

解法三:分治法。要解决规模为n的问题,可递归地解决两个规模近似为n/2的子问题,然后对它们的答案进行合并以得到整个问题的答案。

int MaxSubsequence(int l,int r,int x[])
{
    // insert code here...
    int lmax = 0;
    int rmax = 0;
    int m = 0;
    int sum = 0;

    if (l > r)
    {
        return 0;
    }

    if (l == r)
    {
        return max(0, x[l]);
    }

    m = (l + r) / 2;
    int i = 0;
    for (i = m ;i >= 1; i--)
    {
        sum  += x[i];
        lmax = max(lmax, sum);
    }

    sum = 0;
    for (i = m + 1; i <= r; i++)
    {
        sum += x[i];
        rmax = max(rmax, sum);
    }
    return max3(lmax + rmax, MaxSubsequence(l,m,x),MaxSubsequence(m+1,r,x));
}

解法四:扫描算法

int MaxSubsequence(int n,int x[])
{
    int maxsofar = 0;
    int maxendinghere = 0;
for( int i =0;i < n ;i++)
{
    maxendinghere = max(maxendinghere + x[i], 0);
    maxsofar = max(maxsofar,maxendinghere);
}
return  maxsofar;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值