例如:
已知:
f(0) = 1;
f(1) = 8;
....
f(n) = f(n-1) + f(n-2);
求:
f(80);
这时候就可以用到递归算法把问题分解
f(80) = f(79) + f(78)
f(79) = f(78) + f(77)
....
一直拆分到f(0) + f(1)
递归完成
斐波那契数列了解一下。。。。
算法练习:求最大子数组
首先用暴力求解法解决:
//已知:股票价格数组
int[] priceArray = {100, 113, 110, 85, 105, 102, 86, 63, 81, 101, 94, 106,
101, 79, 94, 90, 97};
//价格波动数组
int[] priceVolatilityArray = new int[priceArray.Length - 1];
//求出价格波动数组
for (int i = 1; i < priceArray.Length; i++)
{
priceVolatilityArray[i - 1] = priceArray[i] - priceArray[i - 1];
}
int total = priceVolatilityArray[0];//默认数组的第一个元素是最大子数组
int startIndex = 0;
int endIndex = 0;
for (int i = 0; i < priceVolatilityArray.Length; i++)
{
//取得以i为子数组起点的所有子数组
for (int j = i; j < priceVolatilityArray.Length; j++)
{
//由i,j就确定了一个子数组
int totalTemp = 0;//临时最大子数组的和
for (int index = i; index < j + 1; index++)
{
totalTemp += priceVolatilityArray[index];
}
if (totalTemp > total)
{
total = totalTemp;
startIndex = i;
endIndex = j;
}
}
}
Console.WriteLine("startIndex = " + startIndex);
Console.WriteLine("endIndex = " + endIndex);
Console.ReadKey();
/*总结:三层for循环嵌套
/* 第一层遍历数组每个元素,目的是求从数组每个元素往后加的情况
* 第二层为了拿到从某个元素开始往后i相加的每一个数
* 第三层用来记录每次累加的值
* 最后把每次累加的值和上一次的做比较得出最大值,并返回i和j的值为最大子数组开始位置
和结束位置
*/
用分治递归法:
//分治法:
//最大子数组结构体
public struct MaxSubArray
{
public int startIndex; //开始时间(用来计算买入时间)
public int endeIndex; //结束时间(卖出)
public int total; //最大子数组之和
}
/// <summary>
/// 取得array从low到high之间的最大子数组
/// </summary>
static MaxSubArray GetMaxSubArray(int[] array, int low, int high)
{
if (low == high) //递归出口:当开始时间和结束时间时同一天,也就是数组分到只有一个元素时
{
MaxSubArray tempMaxSubArray;
tempMaxSubArray.startIndex = low;
tempMaxSubArray.endeIndex = high;
tempMaxSubArray.total = array[low];
return tempMaxSubArray;
}
//三种情况:
int mid = (low + high) / 2; //低区间:low-mid;高区间:mid+1-high;
//low,hugh同时位于低区间时
MaxSubArray maxSubArray1 = GetMaxSubArray(array, low, mid);
//low,high同时位于高区间时
MaxSubArray maxSubArray2 = GetMaxSubArray(array, mid + 1, high);
//low在高区间,high在低区间时
int total1 = array[mid];
int startIndex = mid;
int tempTotal = 0;
//从[low,mid]中找出最大子数组[i,mid]
for (int i = mid; i >= low; i--)
{
tempTotal += array[i];
if (tempTotal > total1)
{
total1 = tempTotal;
startIndex = i;
}
}
//从[mid+1,high]中找出最大子数组[mid+1,j]
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;
}
}
MaxSubArray maxSubArray3;//第一第三种情况下的子数组
maxSubArray3.total = total1 + total2;//最大子数组之和为:从【中间往两边】依次累加的【两个最大子数组之和】相加的结果
maxSubArray3.startIndex = startIndex;
maxSubArray3.endeIndex = endIndex;
/*把三次结果做比较,得出最大子数组*/
MaxSubArray maxSubArrayA = maxSubArray1.total > maxSubArray2.total ? maxSubArray1 : maxSubArray2;
MaxSubArray maxSubArrayB = maxSubArrayA.total > maxSubArray3.total ? maxSubArrayA : maxSubArray3;
return maxSubArrayB;