您的位置:首页 > 其它

LeetCode 121-123 Best Time to Buy and Sell Stock I II III

2017-08-05 11:49 405 查看
LeetCode 121-123 Best Time to Buy and Sell Stock

选择买卖股票的最佳时间,使得利润最大,主要采用动态规划或者贪心算法解决这三道题。

121.
Best Time to Buy and Sell Stock

Say you have an array for which the ithelement
is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find
the maximum profit.
Example 1:

Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)

Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0

In this case, no transaction is done, i.e. max profit = 0.


题意:已知股票每天的价格已保存到一个vector的数组中,数组的第i个数表示股票在第i天的价格,在最多只能完成一次交易的情况下,求能够得到的最大利润。

分析:应采用动态规划法,把第n天之内能够得到的最大利润问题分解为第i天之内能够得到的最大利润问题,并且记录更新最大利润。实现过程可通过从前向后遍历数组,记录当前出现过的最低价格,作为买入价格,并且计算以当天价格作为卖出价格卖出,获得的利润与第i-1天获得的最大利润相比,较大者即为第i天之内能够获得的最大利润,通过整个遍历过程,就可得到第n天之内获得的最大利润,即为所求。时间复杂度为:O(n)

具体代码如下:

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty()) return 0;
int min = prices[0];
int opt = 0;
for (int i = 1; i < prices.size(); i++) {
if (prices[i] < min) {
min = prices[i];
}
else if (opt < prices[i] - min) {
opt = prices[i] - min;
}
}
return opt;
}
};


122. Best Time to Buy and Sell Stock II

Say you have an array for which the ith element
is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times).
However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

题意:同样已知股票每天的价格已保存到一个vector的数组中,数组的第i个数表示股票在第i天的价格,这题的要求与前一题略有不同,可以交易无数次,但是不能同时交易多个股票,也就是说,每次手上至多能够拥有一只股票,求累计的最大收益。

分析:分析可知,应采用贪心算法,从前向后遍历数组,只要当天价格高于前一天价格,即可卖出,每次累加,可得所求最大累计利润。时间复杂度为:O(n)

具体代码如下:

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty())		return 0;
int ans = 0;
int min = prices[0];
for (int i = 0; i < prices.size(); i++) {
if (prices[i] < min) {
min = prices[i];
}
else {
ans += prices[i] - min;
min = prices[i];
}
}
return ans;
}
};


123.
Best Time to Buy and Sell Stock III

Say you have an array for which the ith element
is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note:

You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

题意:同样也是已知股票每天的价格已保存到一个vector的数组中,数组的第i个数表示股票在第i天的价格,不过该题只能给交易两次,并且不能够同时参与多个交易,也即是,每次要买入第二只股票时必须要将手上拥有的股票卖出。

分析:应采用动态规划法,将该题理解成:在第i天卖出第一只股票并且买入第二只股票,使得第一只股票获得的最大利润preProfit加上第二只股票能够获得的最大利润postProfit总和最大。易知,需要求的参数有:preProfit[i](表示第i天之前能够获得的最大利润),postProfit[i](表示第i天之后能够获得的最大利润)。

求解:首先,为求得preProfit[i],从前向后遍历数组,通过变量min记录当前出现过的最低价格,作为买入价格,并且以当天价格prices[i]作为卖出价格,获得的利润prices[i]-min与第i-1天之前能够获得的最大利润preProfit[i-1]相比,较大者即为第i天之前能够获得的最大利润preProfit[i],完成整个遍历过程,就可得到数组preProfit[i](1≤i≤n)。

然后,求postProfit[i],为了求出第i天之后能够获得最大利润,这次需要从后往前遍历数组,通过max记录当前出现过的最高价格,作为卖出价格,并且每次以当天价格prices[i]作为买入价格,获得的利润max-prices[i]与第i+1天之后能够获得的最大利润postProfit[i+1]相比,较大者作为第i天之后能够获得的最大利润postProfit[i],完成整个遍历过程,就可得到数组postProfit[i](0≤i≤n-1)。

求出preProfit[i]和postProfit[i]之后,遍历一次数组,选择出最大的preProfit[i]+postProfit[i],即为所求。时间复杂度为:O(n)

具体代码:

class Solution {
public:
int maxProfit(vector<int>& prices) {
if (prices.empty())	return 0;
int ans = 0;
int* preProfit = new int[prices.size()];
int* postProfit = new int[prices.size()];
int min = prices[0];

preProfit[0] = 0;
for (int i = 1; i < prices.size(); i++) {
if (prices[i] < min)
min = prices[i];
if (prices[i] - min > preProfit[i - 1])
preProfit[i] = prices[i] - min;
else
preProfit[i] = preProfit[i - 1];
}

int max = prices[prices.size() - 1];
postProfit[prices.size() - 1] = 0;
for (int i = prices.size() - 2; i >= 0; i--) {
if (prices[i] > max)
max = prices[i];
if (max - prices[i] > postProfit[i + 1])
postProfit[i] = max - prices[i];
else
postProfit[i] = postProfit[i + 1];
}

for (int i = 0; i < prices.size(); i++) {
if (ans < preProfit[i] + postProfit[i])
ans = preProfit[i] + postProfit[i];
}
return ans;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息