暴力破解法是最简单的实现方法,只要列出数组所有可能的组合,然后找出其中和最大的组合即可;
暴力破解法法分三层循环实现:
1)第一层循环用于固定子数组的起始位置;
2)第二层循环用于确定子数组的结束位置;
3)第三层循环用于子数组和的计算,从子数组的头开始遍历到其尾,累加起来就是该子数组的和。
static void Main(string[] args)//暴力求解
{
int[] priceArray = { 100, 113, 110, 85, 105, 102, 86,63,81,101,94,106,101,79,94,90,97 };
int[] priceFluctionArray = new int[priceArray.Length-1];
for (int i=1; i<priceArray.Length; i++)
{
priceFluctionArray[i - 1] = priceArray[i] - priceArray[i - 1];
}
int total = priceFluctionArray[0];//默认数组的第一个元素 是最大子数组
int startIndex = 0;
int endIndex = 0;
for(int i = 0; i < priceFluctionArray.Length; i++)
{
//取得以i为子数组起点的 所有子数组
for (int j=i;j<priceFluctionArray.Length;j++)
{
//由ij就确定了一个子数组
int totalTemp = 0;//临时 最大子数组的和
for(int index = i; index < j + 1; index++)
{
totalTemp += priceFluctionArray[index];
}
if (totalTemp > total)
{
total = totalTemp;
startIndex = i;
endIndex = j;
}
}
}
Console.WriteLine("startIndex: " + startIndex);
Console.WriteLine("endIndex: " + endIndex);
Console.WriteLine("购买日期 :" + startIndex + "出售日期: " + (endIndex+1));
Console.ReadKey();
}
分治法的精髓:
1)分--将问题分解为规模更小的子问题;
2)治--将这些规模更小的子问题逐个击破;
3)合--将已解决的子问题合并,最终得出“母”问题的解;
所以原数组的最大子数组求法:
1)分--将原数组拆分成两部分,每个部分再拆分成新的两部分......直到数组被分得只剩下一个元素;
2)治--每个小型的数组找最大子数组,只有一个元素的数组,解就是该元素;
3)合--将两个小型数组合并为一个数组,其中解有三种可能:
- 左边的返回值大【low ,mid】
- 中间存在一个更大的子数组和[low,high]
- 右边的返回值大,[mid+1,high]
返回值应选最大的;
//最大子数组的结构体
struct SubArray
{
public int startIndex;
public int endIndex;
public int total;
}
static SubArray GetMaxSubArray(int low, int high, int[] array)//获取最大子数组的
{
if (low == high)
{
SubArray sub;
sub.startIndex = low;
sub.endIndex = high;
sub.total = array[low];
return sub;
}
int mid = (low + high) / 2;//低区间low mid 高区间 mid+1 high
SubArray sub1 = GetMaxSubArray(low, mid, array);
SubArray sub2 = GetMaxSubArray(mid + 1, high, array);
//从【low,mid】找到最大子数组[i,mid]
int total1 = array[mid];
int startIndex = mid;
int totalTemp = 0;
for(int i=mid; i >= low; i--)
{
totalTemp += array[i];
if (totalTemp > total1)
{
total1 = totalTemp;
startIndex = i;
}
}
int total2 = array[mid + 1];
int endIndex = mid + 1;
totalTemp = 0;
for(int j = mid + 1; j <= high; j++)
{
totalTemp += array[j];
if (totalTemp > total2)
{
total2 = totalTemp;
endIndex = j;
}
}
SubArray sub3;
sub3.startIndex = startIndex;
sub3.endIndex = endIndex;
sub3.total = total1 + total2;
if (sub1.total >= sub2.total && sub1.total >= sub3.total) {
return sub1;
}else if (sub2.total >= sub1.total && sub2.total >= sub3.total)
{
return sub2;
}
else
{
return sub3;
}