分治法(递归的解决问题)
分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔
分治算法 - 最大子数组问题
求得价格波动 最大子数组,及和最大的子数组
1,暴力求解
private readonly int[] _priceArray = new[] {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
private void Violence(int[] priceArray)
{
int total = priceArray[0];
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < priceArray.Length; i++)
{
for (int j = i; j < priceArray.Length; j++)
{
//确定一个子数组
int totalTemp = 0;
for (int k = i; k < j + 1; k++)
{
totalTemp += priceArray[k];
}
if (totalTemp > total)
{
total = totalTemp;
startIndex = i;
endIndex = j;
}
}
}
Debug.Log(startIndex + "---" + endIndex); // 7---10
}
2,分治法
public struct SubArray
{
public int StartIndex;
public int EndIndex;
public int Total;
}
private SubArray DivideAndRule(int low, int high, int[] priceArray)
{
if (low == high)
{
SubArray subArray = new SubArray();
subArray.StartIndex = low;
subArray.EndIndex = high;
subArray.Total = priceArray[low];
return subArray;
}
int mid = (low + high)/2; //[low,mid] [mid+1,high]
//1在低区间
SubArray lowSubArray = DivideAndRule(low, mid, priceArray);
//2在高区间
SubArray highSubArray = DivideAndRule(mid + 1, high, priceArray);
//3跨两区间
int total1 = priceArray[mid];
int startIndex = mid;
int endIndex = mid + 1;
int totalTemp = 0;
for (int i = mid; i >= low; i--)
{
totalTemp += priceArray[i];
if (totalTemp > total1)
{
total1 = totalTemp;
startIndex = i;
}
}
int total2 = priceArray[mid + 1];
totalTemp = 0;
for (int i = mid + 1; i <= high; i++)
{
totalTemp += priceArray[i];
if (totalTemp > total2)
{
total2 = totalTemp;
endIndex = i;
}
}
SubArray currSubArray = new SubArray()
{
StartIndex = startIndex,
EndIndex = endIndex,
Total = total1 + total2
};
if (lowSubArray.Total > currSubArray.Total && lowSubArray.Total > highSubArray.Total)
{
return lowSubArray;
}
if (currSubArray.Total > lowSubArray.Total && currSubArray.Total > highSubArray.Total)
{
return currSubArray;
}
return highSubArray;
}