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[] priceFluctuationArray = new int[priceArray.Length-1];//价格波动的数组
for (int i = 1; i < priceArray.Length; i++)
{
priceFluctuationArray[i - 1] = priceArray[i] - priceArray[i - 1];
}
int total = priceFluctuationArray[0];//默认数组的第一个元素 是最大子数组
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < priceFluctuationArray.Length; i++)
{
//取得以i为子数组起点的 所有子数组
for (int j = i; j < priceFluctuationArray.Length; j++)
{
//由i j 就确定了一个子数组
int totalTemp = 0;//临时 最大子数组的和
for (int index = i; index < j + 1; index++)
{
totalTemp += priceFluctuationArray[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:买入日期在左边,卖出时间在右边
最终比较三种情况的大小即可得出结果
介绍至此已经可以开始编程了
class Program
{
//最大子数组的结构体
struct SubArray
{
public int startIndex;
public int endIndex;
public int total;
}
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[] pf = new int[priceArray.Length - 1];//价格波动的数组
for (int i = 1; i < priceArray.Length; i++)
{
pf[i - 1] = priceArray[i] - priceArray[i - 1];
//Console.WriteLine(pf[i-1]);
}
int left = 0;
int right = pf.Length - 1;
var sub = GetMaxSub(left, right, pf);
Console.WriteLine(sub.total);
Console.ReadKey();
}
//这个方法是用来取得array 这个数组 从low到high之间的最大子数组
private static SubArray GetMaxSub(int left, int right, int[] array)
{
if (left == right)
{
SubArray subArray;
subArray.endIndex = right;
subArray.startIndex = left;
subArray.total = array[left];
return subArray;
}
// 左边区间 [left,mid] 右边区间[mid+1,right]
var mid = (left + right) / 2;
//情况1:买入和卖出的日期均在左边
var array1 = GetMaxSub(left, mid, array);
//情况2:买入和卖出的日期均在右边
var array2 = GetMaxSub(mid + 1, right, array);
//情况3:买入日期在左边,卖出时间在右边
int totalTemp1 = 0;
int startIndex = mid;
int endIndex = mid;
int total1 = array[mid];
for (int i = mid; i > 0; i--)
{
totalTemp1 += array[i];
if (total1 < totalTemp1)
{
startIndex = i;
total1 = totalTemp1;
}
}
int totalTemp2 = 0;
int total2 = array[mid + 1];
for (int i = mid + 1; i > array.Length; i++)
{
totalTemp2 += array[i];
if (total2 < totalTemp2)
{
endIndex = i;
total2 = totalTemp2;
}
}
SubArray array3;
array3.endIndex = endIndex;
array3.startIndex = startIndex;
array3.total = total1 + total2;
return GetMaxThree(array1, array2, array3);
}
private static SubArray GetMaxThree(SubArray sub1, SubArray sub2, SubArray sub3)
{
SubArray max;
max.total = 0;
//int temp=0;
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;
}
}
}