最大股票收益问题(数组最大差问题)

来源:互联网 发布:日本菜刀 知乎 编辑:程序博客网 时间:2024/05/21 18:23

最大股票收益问题(数组最大差问题)

问题描述

给定一个数组,存储着按照时间排序的股票价格,第i个位置的元素为第i次交易时的股票价格;现假设只允许你进行一次买,然后在某一时刻卖出(单只股票),请设计算法,求解你可能获得的最大收益,如果股价是非增的,则收益为0。

O(n2)解法

将数组每个元素与其后的所有元素比较,选择增差最大的一对儿。
时间复杂度为:

T(n)=(n1)+(n2)+......+1

O(nlogn)解法

算法思想

采用分而治之的思想,将数组对半分,则最大收益分以下3中情况:
- 在前半段中买并卖
- 在后半段中买并卖
- 在前半段买,在后半段卖
对于第1种和第2种情况,只需要将其看作一个规模减小的新的问题,也就是迭代我们的算法;对于第3种情况,需要在前半段找最小元素min,在后半段找最大元素max,则maxmin是第3种情况下的可能的最优解。

伪代码

void stock(int K[], int startIndex, int endIndex){    int length = endIndex - startIndex;    if(1==length) return 0;    if(2==length) return K[endIndex]-K[startIndex] > 0 ? K[endIndex]-K[startIndex] : 0;    if(length>2){        midIndex = (startIndex+endIndex)/2;        min = findMin(K, startIndex, midIndex );        max = findMax(K, midIndex+1, endIndex);        mayGet = max(stock(K,startIndex,midIndex), stock(K,startIndex,midIndex), max-min);        return mayGet > 0 ? mayGet : 0;    }}

复杂度

T(n)=2T(n2)+n2+n2

解得:
T(n)=O(nlogn)

O(n)解法

算法思想

预处理数组,转化为求数组最大子段和问题,然后使用最大子段和的求解算法解决该问题。

步骤:

预处理数组

将数组的每一项减去其紧挨着的前一项,首项设为0;
其含义为:将股价数组,变为股价增幅数组。
如:

K = [3,5,1,2,5,8,9,6]

处理之后变为

K = [0,2,-4,1,3,3,1,-3]

预处理之后,原问题就转化为求数组最大子段和的问题。
例如,在原数组中很显然最大收益为91=8,则在预处理之后的数组中,只需要从1之后的第一个元素开始到9所对应的元素为止,进行累加即可,为1+3+3+1=8
这其中的道理也很简单,因为预处理之后的数组存储的正是增量,将两个元素之间的所有增量累加,得到的正是两个元素的差值。
预处理算法伪代码:

void preProcess(int K[], int n){    int i;    i = n-1;    while(i>0){        K[i] = k[i]-k[i-1];    }    K[0] = 0;}

求最大子段和

那么最大收益的问题就转化成为了求数组最大子段和的问题,针对最大子段和采用以下算法。
先看伪代码:

void maxSegSum(int K[], int n){    int i;    int maxSum=-MAXINT;    int tempSum=0;    for(i=0; i<n; i++){        tempSum += K[i];        if(tempSum>maxSum) maxSum = tempSum;        if(tempSum<0) tempSum=0;    }       print("max sub-segment sum is %f", maxSum);}

算法描述:
- 从头到尾遍历数组,维持两个全局变量,maxSum记录最优解,tempSum记录从某个位置开始的子段和;
- 每次更新tempSum之后,先和maxSum进行比较,大于maxSum则更新maxSum;然后检查tempSum是否小于0,如果否继续累加,如果是则将tempSum归零;
- 这样遍历一遍数组之后,得到的maxSum就是该数组的最大子段和。

算法综述

  • 预处理数组,转化为最大子段和问题O(n)
  • 使用以上算法求解最大子段和问题O(n)

时间复杂度

T(n)=O(n)+O(n)

即:
T(n)=O(n)

原创粉丝点击