问题描述
参见上文
问题分析
选择序列Array(0..n)
中任一元素Array[i]
作为基点,问题转化为寻找该元素(包括该元素)之前所有元素的单次交易最大收益值MaxProfit_Array(0..i)
,和该元素之后所有元素的单次交易大收益值MaxProfit_Array(i+1..n)
。
寻找序列中单次交易最大收益值
- 遍历算法
public static long calcSubMaxProfit(int[] p_samples, int startIndex, int endIndex)
{
long maxProfit = 0; //返回值,最大利润;
int startSample = 0;//局部变量;买入值;
int endSample = 0;//局部变量;卖出值;
if (startIndex <= endIndex)
{
for (int i = startIndex; i < endIndex; i++) //固定买卖开始样本点
{
startSample = p_samples[i];
for (int j = i+1; j <= endIndex; j++) //固定买卖结束样本点
{
endSample = p_samples[j];
maxProfit = compareAndSwap(maxProfit, endSample - startSample);
}
}
}
return maxProfit;
}
- 递推算法
public static long calcSubMaxProfit_EX(int[] p_samples, int startIndex, int endIndex)
{
long maxProfit = 0; //返回值,最大利润;
if (startIndex <= endIndex)
{
long minSample = p_samples[startIndex];//最小买入值;
for (int i = startIndex; i <= endIndex; i++) //卖出样本点
{
minSample = compareAndSwap_min(minSample, p_samples[i]);
maxProfit = compareAndSwap(maxProfit, p_samples[i] - minSample);
}
}
return maxProfit;
}
算法实现
/** * 计算最多两次买卖最大收益 * * @param p_samples: 样本数组; * @param len: 数组长度; * * 如果样本个数小于2,不够一次买卖操作,直接返回; * 步骤一:寻找第一次买卖节点,计算本次交易最大收益; * 步骤二:提取剩余样本数据,计算第二次交易最大收益; * 步骤三:将两次交易之和与缓存最大交易收益值比较,缓存最大值。 * * */
public static long calcMaxProfit_EX(int[] p_samples, int len)
{
long maxProfit = 0; //返回值,最大利润;
long fisrtTransProfit[] = new long[len];
long secondTransProfit[] = new long[len];
if (len >= 2)
{
for (int i = 0; i < len; i++) //固定第一次买卖开始样本点
{
fisrtTransProfit[i] = calcSubMaxProfit(_EX)(p_samples, 0, i);
secondTransProfit[i] = calcSubMaxProfit(_EX)(p_samples, i+1, len-1);
maxProfit = compareAndSwap(maxProfit, fisrtTransProfit[i]+secondTransProfit[i]);
}
}
return maxProfit;
}
性能分析
选取500个样本数据:
Array[0..499] = {10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80, 10,3,800,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80, 10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80, 10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80, 10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,300,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80,10,3,80,11,20,22,5,75,65,80};
算法类别 | 耗时(毫秒) |
---|---|
遍历实现 | 25~31 |
递推实现 | 3~4 |