问题描述:
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
For example, given the array [−2,1,−3,4,−1,2,1,−5,4],
the contiguous subarray [4,−1,2,1] has the largest sum = 6.
问题分析(参考了算法导论第4章分治策略的内容):
为求一个含负数的一组数种,和为最大的子数组
这里使用分治的思想
首先,这一个子数组它只可能以3种方式存在:
完全在上半部分:low--mid
完全在下半部分:mid--high
或者跨越中点地存在:可理解为Arr[i..mid]+[mid+1..j]最大的元素和组成
算法的思想:递归地寻求左、右部分的最大子数组和
最后合并每次递归结果的解(只保留最后最大的结果)
时间复杂度分析:
n=1 T(1)=Θ(1)
n>1 子问题——求解左子数组和右子数组;每组子问题求解花费T(n/2)
所以算法的运行时间T(n)递归式为:
T(n)={ Θ(1) ,n=1
2T(n/2) ,n>1
最后可以求解出T(n)=Θ(nlgn)
#include<iostream>
#include<climits>
using namespace std;
const int infinite=-;
int Find_Max_Crossing_Subarray(int arr[],int low,int mid,int high)//扫描上半部分最大和、下半部分最大和,上下部分结合为跨越中点最大和
{ int left_sum=infinite;
int right_sum=infinite;
int max_left=-,max_right=-,sum=;
for(int i=mid; i>=low; i--)
{
sum+=arr[i];
if(sum>left_sum)
{
left_sum=sum;
max_left=i;
}
}
sum=;
for(int j=mid+; j<=high; j++)
{
sum+=arr[j];
if(sum>right_sum)
{
right_sum=sum;
max_right=j;
}
}
return (left_sum+right_sum);
}
int Find_Maximum_Subarray(int arr[],int low,int high)//
{
if(high==low)//只有一个元素的时候
return arr[low];
else
{
int mid=(low+high)/;
int leftSum=Find_Maximum_Subarray(arr,low,mid);
int rightSum=Find_Maximum_Subarray(arr,mid+,high);
int crossSum=Find_Max_Crossing_Subarray(arr,low,mid,high);
if(leftSum>=rightSum&&leftSum>=crossSum)
return leftSum;
else if(rightSum>=leftSum&&rightSum>=crossSum)
return rightSum;
else return crossSum;
}
}
int main()
{
int arr[]= {,,,-,,,,,-,};
int ans=Find_Maximum_Subarray(arr,,);
cout<<ans<<endl;
return ;
}