这是一道我在网上看到的亚马逊电话面试题目
给出一组股票价格,他们已经按时间排序好,找出什么时候买入什么时候卖出的时间点,使得利润最大。
抽象成算法题目应该是这样的:
给定一个数组,暂且认为是整型数组,找出前后差值最大的下标。例如:
若给定数组:9, 2,3, 5,1。那么返回下标应为1和3,因为5和2是前后差值最大的,9和2不行,因为9出现在2之前。
这道题目和从无序数组中找出第N大的类似,解法几乎是一样的。我的解法如下:
首先找出一个候选答案(注意,候选答案未必存在!!!不是每个股票都能在给定的时间内盈利的。)然后,以候选答案为基准,寻找下一个候选答案。代码如下:
typedef std::pair<int, int> MaxProfitPair;
MaxProfitPair GetMaxProfitPair(int * pArray, const int iSize)
{
MaxProfitPair cMaxProfitPair(-1, -1);
if (NULL == pArray || iSize <= 1)
{
return cMaxProfitPair;
}
int iMaxProfit = 0, i = 0;
for (i = 0; i < iSize; ++i)
{
if (pArray[i] < pArray[i + 1])
{
cMaxProfitPair.first = i;
cMaxProfitPair.second = i + 1;
iMaxProfit = pArray[i + 1] - pArray[i];
++i;
break;
}
}
if (-1 == cMaxProfitPair.first && -1 == cMaxProfitPair.second)
{
return cMaxProfitPair;
}
int iLowerIndex = cMaxProfitPair.first;
while (i < iSize)
{
if (pArray[i] < pArray[iLowerIndex])
{
iLowerIndex = i;
}
else if (pArray[i] - pArray[iLowerIndex] > iMaxProfit)
{
cMaxProfitPair.first = iLowerIndex;
cMaxProfitPair.second = i;
iMaxProfit = pArray[i] - pArray[iLowerIndex];
}
++i;
}
return cMaxProfitPair;
}
这里-1作为无效的下标值,若发现返回值是-1,则认为无法获取利润。以下是测试代码,同样省去无效参数等测试用例,仅仅测试代码算法正确性:
int main()
{
int pTestArray1[] = {5, 0, 4, 1, 3, 5, 8, 9};
int pTestArray2[] = {5, -1, -1, 9, 7, 5, 3, 1};
int pTestArray3[] = {7, 2, 5, 5, 8, 2, 3, 4, 7, 4};
int pTestArray4[] = {9, 2, 6, 5, 8, 2, 3, 4, 7, 10, 3, 8};
int pTestArray5[] = {7, 3, 4, 12, 10, 9, 2, 5, 1, 3};
int pTestArray6[] = {1, -1, -1, 6};
int* ppTest[] = {
pTestArray1,
pTestArray2,
pTestArray3,
pTestArray4,
pTestArray5,
};
int iCount = sizeof(ppTest) / sizeof(*ppTest);
for (int i = 0; i < iCount; ++i)
{
MaxProfitPair p = GetMaxProfitPair(ppTest[i] + 3, ppTest[i][0]);
if (p.first != ppTest[i][1] && p.second != ppTest[i][2])
{
std::cout << "pTestArray" << i + 1 << " testing got wrong!";
std::cout << " it returned: " << p.first << ", " << p.second << std::endl;
}
else
{
std::cout << "pTestArray" << i + 1 << " testing got correct!\n";
}
}
getchar();
}