您的位置:首页 > 其它

Best Time to Buy and Sell Stock I II III IV (第四周 动态规划)

2017-03-17 13:53 375 查看

Best Time to Buy and Sell Stock I II III IV (第四周 动态规划)

Best Time to Buy and Sell Stock I

Say you have an array for which the ith element 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:

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:

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

Output: 0

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

算法思路

使用动态规划,从左到右遍历一遍数组,记录一下当前出现的最低的股票价格,并且与当前股票价格作对比,如果当前的更低,就更新最低股票价格,并且用当前股票价格减去最低股票价格得到可能的最大收益,并且与全局最大收益对比,取最大。

算法代码

class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len == 0)
return 0;
int res = 0;
int cur = prices[0];
for(int i = 0; i < prices.size(); i++){
cur = min(cur,prices[i]);
res = max(res,prices[i] - cur);
}
return res;
}
};


时空复杂度

时间复杂度:O(n)

空间复杂度:O(1)

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).

Subscribe to see which companies asked this question.

算法思路

使用贪心算法,从左到右遍历数组,只要当前股票价格大于前一天的价格,就会有收益,当前的差值就是今天的收益,我们累加这些差值,就可以得到最终的收益。

算法代码

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


时空复杂度

时间复杂度:O(n)

空间复杂度:O(1)

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).

Subscribe to see which companies asked this question.

算法思路

使用动态规划,也使用到了二分的思想。以第i天为一个分解析,我们要维护两个数组pre与post,pre[i]与post[i]分别表示第i天之前进行一次交易的最大收益和第i天之后进行一次交易的最大收益。最后再遍历一遍数组,得到max{pre[i] + post[i]} 就是最大的收益。至于pre和post的值的求法和Best Time to Buy and Sell Stock I是一样的,都是用动态规划的方法在线性时间内求得。要注意的是,pre是从前往后遍历数组,而post是从后往前遍历数组。

算法代码

class Solution {
public:
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len == 0)
return 0;

int res = 0,preres[99999],postres[99999];
int tmp;

for(int i = 0 ; i < len; i++)
postres[i] = 0, preres[i] = 0;

tmp = prices[0];
int cur = 0;
for(int i = 1; i < len; i++){
tmp = min(tmp,prices[i]);
preres[i] = max(cur,prices[i] - tmp);
cur = max(preres[i],cur);
}

tmp = prices[len - 1];
cur = 0;
for(int i = len - 2; i >= 0; i--){
tmp = max(tmp,prices[i]);
postres[i] = max(cur,tmp - prices[i]);
cur = max(postres[i],cur);
}

for(int i = 0; i < len; i++)
res = max(res,postres[i] + preres[i]);

return res;
}
};


时空复杂度

时间复杂度:O(n)

空间复杂度:O(n)

Best Time to Buy and Sell Stock IV

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 k transactions.

Note:

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

算法思路

用特殊的动态规划。我们先定义两个矩阵local与global,local[i][j]为在到达第i天时最多可进行j次交易并且最后一次交易在最后一天卖出的最大利润,此为局部最优。global[i][j]为在到达第i天时最多可进行j次交易的最大利润,此为全局最优。然后动态规划的转移公式为:

local[i][j] = max(global[i - 1][j - 1] + max(diff, 0), local[i - 1][j] + diff)

global[i][j] = max(local[i][j], global[i - 1][j]),

其中局部最优值是比较前一天并少交易一次的全局最优加上大于0的差值,和前一天的局部最优加上差值后相比,两者之中取较大值,而全局最优比较局部最优和前一天的全局最优。要注意的是,如果k的值远大于prices的天数,该dp算法会很慢,应该直接使用Best Time to Buy and Sell Stock II 的贪心算法求解。

算法代码

class Solution {
public:
int maxProfit(int k, vector<int> &prices) {
if (prices.empty()) return 0;
if (k >= prices.size()) return solveMaxProfit(prices);
int g[k + 1] = {0};
int l[k + 1] = {0};
for (int i = 0; i < prices.size() - 1; ++i) {
int diff = prices[i + 1] - prices[i];
for (int j = k; j >= 1; --j) {
l[j] = max(g[j - 1] + max(diff, 0), l[j] + diff);
g[j] = max(g[j], l[j]);
}
}
return g[k];
}
int solveMaxProfit(vector<int> &prices) {
int res = 0;
for (int i = 1; i < prices.size(); ++i) {
if (prices[i] - prices[i - 1] > 0) {
res += prices[i] - prices[i - 1];
}
}
return res;
}
};


时空复杂度

时间复杂度:O(n)

空间复杂度:O(k)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划