目录
-
买股票的最佳时机II
给定一个数组,它的第i个元素是一支给定股票第i天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1:
输入:[7,1,5,3,6,4]
输出:7
解释:在第2天(股票价格= 1)的时候买入,在第3天(股票价格= 5)的时候卖出,这笔交易所能获得利润= 5-1 = 4。
随后,在第4天(股票价格= 3)的时候买入,在第5天(股票价格= 6)的时候卖出,这笔交易所能获得利润= 6-3 = 3。
示例2:
输入:[1,2,3,4,5]
输出:4
解释:在第1天(股票价格= 1)的时候买入,在第5天(股票价格= 5)的时候卖出,这笔交易所能获得利润= 5-1 = 4。
注意你不能在第1天和第2天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例3:
输入:[7,6,4,3,1]
输出:0
解释:在这种情况下,没有交易完成,所以最大利润为0。
测试单元
首先我们先来写测试单元:由题目给出的例子可以写三个种测试单元(乱序股票,顺序股票,逆序股票)股票价格一直不变即可归为排序的股票(逆序,顺序) 。
#include <stdio.h>
#include <stdlib.h>
int main()
{
int prices1[6] = { 7, 1, 5, 3, 6, 4 };
int prices2[5] = { 1, 2, 3, 4, 5 };
int prices3[5] = { 7, 6, 4, 3, 1 };
int sum1 = maxProfit(prices1, 6);
int sum2 = maxProfit(prices2, 5);
int sum3 = maxProfit(prices3, 5);
printf("%d%,%d,%d", sum1, sum2, sum3);
system("pause");
return 0;
}
题目分析
解决买股票问题而且要达到利润最大化,就需要讨论如何购买股票(购买股票的时机,出售股票的时机)由于我们知道全部股票的价格,并非像现实生活中的那样,我们只需要从一堆数据中用一个算法来选择购买的时机,出售得到时机即可达到利润最大化。(低价买入,高价出售)我们需要创建两个变量来存放股票一个交易阶段的购买日(最低价)出售日(最高价)直到股票的最后一日。
购买股票的时机:从第一天开始,向后确定一个相比与第一天股票价格低得日子作为购买日(或者第一天比第二天低就确定第一天为购买日)
出售股票得时机:从购买日向后确定一个相比购之日之后得那天股票价格高得日子作为出售日。
然后将第二次购买日从放到第一次出售日(交易日)的后一天开始遍历(按购买日的要求遍历)
再确定第二次出售日,以此类推,直到最后一个交易日截至。(必须确定购买日,交易日,然后再交易,增加利润)。
代码如下:
标准版
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int maxProfit(int* prices, int pricesSize)
{
assert(prices);
int min = 0, max = 0;
int i = 0, j = 0;
int sum = 0;
while (i < pricesSize - 1)//到最后一个交易日截至
{
if (prices[i] < prices[i + 1])//确定购买日
{
min = i;
for (j = i + 1; j < pricesSize; j++)//遍历
{
if (j == (pricesSize - 1) || prices[j] > prices[j + 1])//从而确定出售日
{
max = j;
break;
}
}
sum += (prices[max] - prices[min]);//利润
i = j + 1;//第二次购买日的起始
}
else
i++;
}
return sum;
}
int main()
{
int prices1[6] = { 7, 1, 5, 3, 6, 4 };
int prices2[5] = { 1, 2, 3, 4, 5 };
int prices3[5] = { 7, 6, 4, 3, 1 };
int sum1 = maxProfit(prices1, 6);
int sum2 = maxProfit(prices2, 5);
int sum3 = maxProfit(prices3, 5);
printf("%d%,%d,%d", sum1, sum2, sum3);
system("pause");
return 0;
}
巧妙版(简称投机取巧版)
要想获得利润最大化那就要抓住每次能获取利润的机会。打破题目中的要求(题目本应当是一天只能交易一次,但投机取巧,能获得最大股价就是利用好每一次涨跌的利润),你会发现,这种想法虽然不符合题目要求,但是可以得到相同的的答案。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int maxProfit(int* prices, int pricesSize)
{
int i, max = 0; //定义买入初值跟,卖出最大值(股价)
for (i = 1; i < pricesSize; i++)
{
if (prices[i]>prices[i - 1]) //如果第一天股价大于第二天股价就卖出,题目本应当是一天只能交易一次,但投机取巧,能获得最大股价就是利用好每一次涨跌的利润。
{
max = max + prices[i] - prices[i - 1]; //利润叠加
}
}
return max;
}
int main()
{
int prices1[6] = { 7, 1, 5, 3, 6, 4 };
int prices2[5] = { 1, 2, 3, 4, 5 };
int prices3[5] = { 7, 6, 4, 3, 1 };
int sum1 = maxProfit(prices1, 6);
int sum2 = maxProfit(prices2, 5);
int sum3 = maxProfit(prices3, 5);
printf("%d%,%d,%d", sum1, sum2, sum3);
system("pause");
return 0;
}