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

#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;

}



你可能感兴趣的:(编程之美)