Question:
已知一组整数数据 A1,A2,A3,A4,A5,A6.....AN
找到1组连续数,使他们的和最大,并返回他们的和
例如:-2,11,-4,13,-5,-2
答案:20(11,-4,13)
About:
Program.cs 文件的主入口点,请在编译的时候一定将此文件编译到其中
Algorithm.cs 算法文件,包含了算法的类,根据不同的类名来区别
Document:
统一使用Algorithm.MaxSubsuquenceSumm 命名空间
算法函数统一使用MaxSubsuquenceSum(int [] A,int N)
int [] A 数据数组
N 数据长度(为了与时间长度相统一)
Algorithm 1:
最简单的方法,通过枚举每组的开始点和结束点,将所有的答案进行比较,时间最长O(N^3)
Algorithm 2:
确定开始点再累加,前一种的改良型,意在取消结束点的枚举工作,直接通过累加来逐个判断,时间次长O(N^2)
Algorithm 3:
这个思路上变化很大,他是通过分割整体成2部分,分别算出没部分的最大数组和,以及边缘数组和(即2数组交界处的数组和,最后要将2个边缘数组和相加)
再比较3者的大小关系(通过Max3函数) 时间次短O(N log N)
PS:假如N足够小,那么第3种方法要慢于第2种,很好解释。
Algorithm 4:
Wonderful!最短的代码,最快的速度,不可思议的结果。
不说了,留给自己慢慢体会。
时间最短 O(N)
File:Program.cs
using System;
namespace Algorithm.MaxSubsequenceSum
{
//程序入口点
public class Program
{
public static void Main(string [] args)
{
int Length=args.Length;
int [] number=new int [Length];
int i;
for(i=0;i<Length;i++)
number[i]=Int32.Parse(args[i]);//The same as number[i]=int.Parse(args[i]);
Console.WriteLine("#1 The MaxSubsequenceSum is {0}",Algorithm.MaxSubsequenceSum_1(number,Length));
Console.WriteLine("#2 The MaxSubsequenceSum is {0}",Algorithm.MaxSubsequenceSum_2(number,Length));
Console.WriteLine("#3 The MaxSubsequenceSum is {0}",Algorithm.MaxSubsequenceSum_3(number,Length));
Console.WriteLine("#4 The MaxSubsequenceSum is {0}",Algorithm.MaxSubsequenceSum_4(number,Length));
}
}
}
File:Algorithm.cs
using System;
namespace Algorithm.MaxSubsequenceSum
{
public class Algorithm
{
//Algorithm 1
//Time is O(N^3) Lowest
public static int MaxSubsequenceSum_1(int [] A,int N)
{
int ThisSum,MaxSum,i,j,k;
MaxSum=0;
for(i=0;i<N;i++)
for(j=i;j<=N;j++)
{
ThisSum=0;
for(k=i;k<j;k++)
ThisSum+=A[k];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
}
return MaxSum;
}
//Algorithm 2
//Time is O(N^2) secend Lowest
public static int MaxSubsequenceSum_2(int [] A,int N)
{
int ThisSum,MaxSum,i,j;
MaxSum=0;
for(i=0;i<N;i++)
{
ThisSum=0;
for(j=i;j<N;j++)
{
ThisSum+=A[j];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
}
}
return MaxSum;
}
//Algorithm 3
//Following 3 Method
//Time is O(N log N) secend Fastest(lower than Algorithm 2 if N is small enough)
public static int MaxSubsequenceSum_3(int [] A,int N)
{
return MaxSubSum(A,0,N-1);
}
public static int MaxSubSum(int [] A,int Left,int Right)
{
int MaxLeftSum,MaxRightSum;
int MaxLeftBorderSum,MaxRightBorderSum;
int LeftBorderSum,RightBorderSum;
int Center,i;
if(Left==Right) //Base Case
if(A[Left]>0)
return A[Left];
else
return 0;
Center=(Left + Right)/2;
MaxLeftSum=MaxSubSum(A,Left,Center);
MaxRightSum=MaxSubSum(A,Center+1,Right);
MaxLeftBorderSum=0;LeftBorderSum=0;
for(i=Center;i>=Left;i--)
{
LeftBorderSum+=A[i];
if(LeftBorderSum>MaxLeftBorderSum)
MaxLeftBorderSum=LeftBorderSum;
}
MaxRightBorderSum=0;RightBorderSum=0;
for(i=Center+1;i<=Right;i++)
{
RightBorderSum+=A[i];
if(RightBorderSum>MaxRightBorderSum)
MaxRightBorderSum=RightBorderSum;
}
return Max3(MaxLeftSum,MaxRightSum,MaxLeftBorderSum+MaxRightBorderSum);
}
public static int Max3(int a,int b, int c)
{
if(a>b)
{
if(a>c)
return a;
else
return c;
}
else
{
if(b>c)
return b;
else
return c;
}
}
//Algorithm 4
//Time is O(N)
//Wonderful
public static int MaxSubsequenceSum_4(int [] A,int N)
{
int ThisSum,MaxSum,j;
ThisSum=MaxSum=0;
for(j=0;j<N;j++)
{
ThisSum+=A[j];
if(ThisSum>MaxSum)
MaxSum=ThisSum;
else if(ThisSum<0)
ThisSum=0;
}
return MaxSum;
}
}
}