最大连续子序列问题

28 篇文章 2 订阅
16 篇文章 0 订阅

一、穷举法

int MaxSubsequence(int *arr, int arrLen)
{
 	int maxSoFar = 0;
 	int max = 0;
 	for(int i = 0; i < arrLen; i++)
 	{
		for(int j = i; j < arrLen; j++)
		{
		    max = 0;
		    for(int k = i; k <= j; k++)
		    {
		        max += arr[k];
		    }
		    if(max > maxSoFar)
			    maxSoFar = max;
		}
    }
    return maxSoFar;
}
上述穷举可以进一步优化,第三个for循环可以省略

int MaxSubsequence(int *arr, int arrLen)
{
 	int maxSoFar = 0;
 	int max = 0;
 	for(int i = 0; i < arrLen; i++)
 	{
        max = 0;
		for(int j = i; j < arrLen; j++)
		{
		    max += arr[j];
		    if(max > maxSoFar)
			    maxSoFar = max;
		}
    }
    return maxSoFar;
}

二、分治法

        最大子序列可能出现在左部分,右部分和跨越左右部分。

int MaxSubsequence(int *arr, int left, int right)
{

 	if(left == right)
        if(arr[left] > 0)
            return arr[left];
        else
            return 0;
  
        int leftMax = 0;
        int rightMax = 0;
    
        int center = (left + right) / 2;
        leftMax  = MaxSubsequence(arr, left, center);
        rightMax = MaxSubsequence(arr, center+1, right);
    
        int max = 0;
        int leftBorder = 0;
        for(int i = center; i >= left; i--)
        {
             max += arr[i];
             if(max > leftBorder)
                 leftBorder = max;
         }
    
        max = 0;
        int rightBorder = 0;
        for(int i = center+1; i <= right; i++)
        {
            max += arr[i];
            if(max > rightBorder)
                rightBorder = max;
        }
    
        return max3(leftMax, rightMax, leftBorder + rightBorder);
       
}


三、线性法

      

int MaxSubsequence(int *arr, int arrLen)
{
 	int maxSoFar = 0;
 	int max = 0;
 	for(int i = 0; i < arrLen; i++)
 	{
	    max += arr[i];
            if(max > maxSoFar)
                maxSoFar = max;
            else if(max < 0)
                max = 0; 
    }
    return maxSoFar;
}

考虑特殊情况,若数组中元素全部为负数,则上述解法得到的最大和为0,这不符合实际要求,应该为最大的负数。

例如:{-2,-4,-1,-8,-3,-5,-12,-34,-7}, 最大连续子序列值应该为-1。

解决办法:只需要在遍历的时候记住序列的最大值即可。

int SubSeq(int *arr, int len)
{
	int maxSoFar = 0;
	int maxVal   = arr[0];
	int sum      = 0;

	for(int i = 0; i < len; i++)
	{
		sum += arr[i];

		if(sum > maxSoFar)
			maxSoFar = sum;
		else if (sum < 0)
			sum = 0;

		if(maxVal < arr[i])
			maxVal = arr[i];
	}

	return maxVal > maxSoFar ? maxVal : maxSoFar;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值