博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

最大子数组和(编程之美2.14,返回下标及首尾相连)

Posted on 2010-09-23 21:22  KurtWang  阅读(1009)  评论(4编辑  收藏  举报
#include "stdafx.h"

//返回下标
int maxSum(int * arr, int len, int & left, int & right)
{
	int start = arr[0];
	int sum = arr[0];
	left=0;
	right=0;
	int cur_left=0,cur_right=0;
	for(int i=1;i<len;i++)
	{
		if(start < 0)
		{
			start = arr[i];
			cur_left=i;
			cur_right=i;
		}
		else
		{
			start+=arr[i];
			cur_right=i;
		}
		
		if(start > sum)
		{
			sum=start;
			left=cur_left;
			right=cur_right;
		}
	}
	return sum;
}

//首尾相连
int maxSum2(int * arr, int len)
{
	int left,right;
	int sum = maxSum(arr,len,left,right);

	//找到arr[0]开始的和最大的一段
	int max=arr[0];
	int temp=max;
	int pos=0;
	for(int i=1;i<len;i++)
	{
		temp+=arr[i];
		if(temp>max)
		{
			max=temp;
			pos=i;
		}
	}

	//找到arr[n-1]开始往后的和最大的一段
	max=arr[len-1];
	temp=max;
	int pos2 = len-1;
	for(int i=len-2;i>0;i--)
	{
		temp+=arr[i];
		if(temp>max)
		{
			max=temp;
			pos2=i;
		}
	}

	//把两段拼接起来
	int sum2=0;
	if(pos<pos2)
	{
		for(int i=0;i<=pos;i++)
			sum+=arr[i];
		for(int i=pos2;i<len-1;i++)
			sum+=arr[i];
		
	}
	else
	{
		for(int i=0;i<len;i++)
			sum2+=arr[i];
	}
	return sum2>sum?sum2:sum;

}

//首尾相连,方法2,先求出和最小的一段子数组,剩下的就是和最大的
int maxSum3(int * arr, int len)
{
	int start = arr[0];
	int sum = arr[0];
	for(int i=1;i<len;i++)
	{
		if(start > 0)
			start = arr[i];
		else
			start+=arr[i];
		
		if(start < sum)
			sum=start;
	}
	
	int totalSum = 0;
	for(int i=0;i<len;i++)
		totalSum += arr[i];

	return totalSum - sum;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int arr[5] = {4,-4,-5,-2,7};
	int left,right;
	int sum = maxSum(arr,5,left,right);
	printf("%d %d %d\n",sum ,left,right);

	sum = maxSum2(arr,5);
	printf("%d\n",sum);

	sum = maxSum3(arr,5);
	printf("%d\n",sum);

	return 0;
}