求哪一天买入和哪一天卖出收益更高?
1.暴力求解
遍历所有的子数组的和进行比较,求出最大值,耗费性能,很耗时间
//价格数组
int[] pricesArray = new int[] { 100,113,110,85,105,102,86,63,81,101,94,106,101,79,94,90,97};
//价格波动数组
int[] priceFluctuationArray = new int[pricesArray.Length];
for (int i = 1; i < pricesArray.Length; i++)
{
priceFluctuationArray[i - 1] = pricesArray[i] - pricesArray[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 (total < totalTemp)
{
total = totalTemp;
startIndex = i;
endIndex = j;
}
}
}
2.分治法
分为[low,mid] 和[mid,high]
1.i,j同时位于低区间:可以继续使用递归进行解决
2.i,j同时位于高区间
3.i位于低区间,j位于该区间:取低区间中到Mid的最大主和取高区间Mid+1到High的最大值相加
//子数组的结构体
struct SubArray
{
public int startIndex;
public int endIndex;
public int total;
}
static void Main(string[] args)
{
//价格数组
int[] pricesArray = new int[] { 100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97 };
//价格波动数组
int[] priceFluctuationArray = new int[pricesArray.Length];
for (int i = 1; i < pricesArray.Length; i++)
{
priceFluctuationArray[i - 1] = pricesArray[i] - pricesArray[i - 1];
}
SubArray maxSubArrar = GetMaxSubArray(0, priceFluctuationArray.Length - 1, priceFluctuationArray);
Console.Write(maxSubArrar.startIndex + "||" + maxSubArrar.endIndex);
Console.ReadKey();
}
/// <summary>
/// 这个方法是取得array数组从low到high的最大子数组
/// </summary>
/// <param name="low"></param>
/// <param name="high"></param>
/// <param name="array"></param>
static SubArray GetMaxSubArray(int low,int high,int[] array )
{
if (low == high)
{
SubArray subArray;
subArray.startIndex = low;
subArray.endIndex = high;
subArray.total = array[low];
return subArray;
}
int mid = (low + high) / 2;//低区间是low-mid,高区间是mid+1-high
SubArray subArray1 = GetMaxSubArray(low, mid, array);
SubArray subArray2 = GetMaxSubArray(mid + 1, high, array);
//从[low,mid]中找到最大子数组
int total1 = array[mid];//最大子数组的和
int totalTemp = 0;
int startIndex = mid;
for (int i = mid; i >=low;i--)
{
totalTemp += array[i];
if (totalTemp > total1)
{
total1 = totalTemp;
startIndex = i;
}
}
//从mid+1到high之间找到最大的
int total2 = array[mid + 1];
int endindex = mid + 1;
totalTemp = 0;
for (int i = mid+1; i <= high; i++)
{
totalTemp += array[i];
if (total2 < totalTemp)
{
total2 = totalTemp;
endindex = i;
}
}
SubArray subArray3;
subArray3.endIndex = endindex;
subArray3.startIndex = startIndex;
subArray3.total = total1 + total2;
if (subArray1.total >= subArray2.total && subArray1.total >= subArray3.total)
{
return subArray1;
}else if (subArray2.total > subArray1.total && subArray2.total > subArray3.total)
{
return subArray2;
}
else
{
return subArray3;
}
}
}