分治法的设计思想是: 将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
问题:求数列的最大字段和
股票问题
日期 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
价格 | 100 | 55 | 110 | 85 | 105 | 102 | 86 | 63 | 81 | 101 | 94 | 106 | 101 | 79 | 94 | 90 | 97 |
变化 | -45 | 55 | -25 | 20 | -3 | -16 | -23 | 18 | 20 | -7 | 12 | -5 | -22 | 15 | -4 | 7 |
从0索引开始 数组中最小的值 到 数组中最大的值 之和的一个数组
//例如 55 – 135 这段数组就是最大子数组
//价格数组
static int[] priceArray = { 100, 55, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106, 101, 79, 94, 90, 97, 80, 120, 135, 90 };
static int[] priceFluctuationArray = new int[priceArray.Length - 1]; //变化数组
暴力求解方式
int total = priceFluctuationArray[0]; //默认数组第一个元素是最大子数组
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < priceFluctuationArray.Length; i++)
{
for (int j = i; j < priceFluctuationArray.Length; j++)
{
int tempSum = 0;
for (int k = i; k < j + 1; k++)
{
tempSum += priceFluctuationArray[k];
}
if (tempSum > total)
{
total = tempSum;
startIndex = i;
endIndex = j;
}
}
}
Debug.Log(string.Format("买入日期:{0} 卖出日期:{1}", startIndex, (endIndex + 1)));
分治法求解
private SubArray FenZi(int low, int high, int[] array)
{
for (int i = 1; i < priceArray.Length; i++)
{
//变化价格 == 价格数组第i个 - 价格数据第i - 1个;
priceFluctuationArray[i - 1] = priceArray[i] - priceArray[i - 1];
}
if (low == high)
{
SubArray subArray;
subArray.startIndex = low;
subArray.endIndex = high;
subArray.total = array[low];
return subArray;
}
int mid = (low + high) / 2;
SubArray subArray1 = FenZi(low, mid, array);
SubArray subArray2 = FenZi(mid + 1, high, array);
int total1 = array[mid];
int startIndex = mid;
int temptotal = 0;
for (int i = mid; i >= low; i--)
{
temptotal += array[i];
if (temptotal > total1)
{
total1 = temptotal;
startIndex = i;
}
}
int total2 = array[mid + 1];
int endIndex = mid + 1;
temptotal = 0;
for (int j = mid + 1; j < high; j++)
{
temptotal += array[j];
if (temptotal > total2)
{
total2 = temptotal;
endIndex = j;
}
}
SubArray subArray3;
subArray3.startIndex = startIndex;
subArray3.endIndex = endIndex;
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;
}
}
struct SubArray
{
public int startIndex;
public int endIndex;
public int total;
}
调用
void Start()
{
for (int i = 1; i < priceArray.Length; i++)
{
//变化价格 == 价格数组第i个 - 价格数据第i - 1个;
//-45 55 -25 20 -3 -16 -23 18 20 -7 12 -5 -22 15 -4 7 -17 40 15 -45
priceFluctuationArray[i-1] = priceArray[i] - priceArray[i - 1];
}
SubArray subArray = FenZi(0, priceFluctuationArray.Length - 1, priceFluctuationArray);
Debug.Log(string.Format("买入日期:{0} 卖出日期:{1}", subArray.startIndex, (subArray.endIndex + 1)));
}