一、暴力解法实现
输入一个整形数组,求数组中连续的子数组使其和最大
对数组内每一个数A[i]进行遍历,然后遍历以它们为起点的子数组,比较各个子数组的大小,找到最大连续子数组

public  static  void MaxArray(int[] array)
{
int maxValue = array[0]; //记录最大子数组的和
int minIndex = 0;//记录子数组的底
int maxIndex = 0;//记录子数组的高

for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length; j++)
{
//所遍历出来的子数组的和
int temp = 0;
//计算遍历的子数组之和
for (int k = i; k <=j; k++)
{
temp += array[k];
}

if (temp>maxValue)
{
maxValue = temp;
minIndex = i;
maxIndex = j;

}
}
}

Console.WriteLine("最大子数组的和是:{0},索引的起始位置:{1},结束位置:{2}",maxValue,minIndex,maxIndex);
}

二:分治法
因为最大子序列和可能在三处出现,整个出现在数组左半部,或者整个出现在右半部,又或者跨越中间,占据左右两半部分。递归将左右子数组再分别分成两个数组,直到子数组中只含有一个元素,退出每层递归前,返回上面三种情况中的最大值。
使用分治技术意味着我们要将子数组划分为两个规模尽量相等的子数组,也就是找到子数组的中央位置(比如mid),然后考虑求解两个子数组A[low…mid]和A[mid+1…high]。A[low…high]的任意连续子数组A[i…j]所处的位置必然是以下三种情况之一:

(a)完全位于子数组A[low…mid]中,因此low≤i≤j≤mid

(b)完全位于子数组A[mid+1…high]中,因此mid≤i≤j≤high

(c)跨越了中点,因此low≤i≤mid≤j≤high

所以我们需要求解这三种情况的最大子数组,然后再取最大值。A[low…mid]和A[mid+1…high]可以递归求解,剩下的就是训中跨越中点的最大子数组

分治法求数组中连续和最大子数组_最大子数组


分治法求数组中连续和最大子数组_子数组_02

public struct SubArray
{
public int StartIndex;//开始索引
public int EndIndex; //结束索引
public int Sum; //和
}
/// <summary>
/// 分治法解决
/// </summary>
public static class DivideAndConquer
{

public static SubArray GetMaxArray(int low, int high, int[] array)
{
if (low==high)
{
SubArray subArray;
subArray.StartIndex = low;
subArray.EndIndex = high;
subArray.Sum = array[low];
return subArray;
}
int mid = (low+high)/2;
SubArray subArray1=GetMaxArray(low,mid,array);
SubArray subArray2=GetMaxArray(mid + 1, high, array);

//低区间最大子数组
int Sum1 = array[mid];
int StartIndex = mid;
int MaxTemp1=0;
for (int i = mid; i >=low; i--)
{
MaxTemp1 += array[i];
if (Sum1<MaxTemp1)
{
Sum1 = MaxTemp1;
StartIndex = i;
}
}

//高区间最大子数组
int Sum2 = array[mid+1];
int MaxTemp2 = 0;
int EndIndex = mid+1;
for (int i = mid+1; i <=high; i++)
{
MaxTemp2 += array[i];
if (Sum2<MaxTemp2)
{
Sum2 = MaxTemp2;
EndIndex = i;
}
}
SubArray subArray3;
subArray3.StartIndex = StartIndex;
subArray3.EndIndex = EndIndex;
subArray3.Sum = Sum1 + Sum2;


//三个可能的数组和进行比较
if (subArray1.Sum>=subArray2.Sum&&subArray1.Sum>=subArray3.Sum)
{
return subArray1;
}
else if(subArray2.Sum >= subArray1.Sum && subArray2.Sum >= subArray3.Sum)
{
return subArray2;
}
else
{
return subArray3;
}

}
}
class Program
{
static void Main(string[] args)
{
int[] sum = {-10,55,22,-22};
SubArray subArray=DivideAndConquer.GetMaxArray(0, sum.Length - 1, sum);
Console.WriteLine("最大子数组的和是:{0},索引的起始位置:{1},结束位置:{2}", subArray.Sum, subArray.StartIndex, subArray.EndIndex);
Console.ReadKey();
}
}