「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战」
说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)
作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题意描述
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:prices = [3,3,5,0,0,3,1,4] 输出:6 解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。 随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
示例 2:
输入:prices = [1,2,3,4,5] 输出:4 解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
题外话: 前几天总结了买卖股票最佳时机④版本的思路,今天总结③版本的思路。
分析
假设我们用净利润解释,变量为统计的最大利润值。有下面的情况
- 第一天如果买了第一笔,说明花掉股票钱。
- 第一天如果卖了,说明第一天买了马上卖,利润为0。
- 第一天如果买入第二笔交易,说明第一天肯定买卖了第一笔,所以第一笔不赚钱,再花股票钱。
- 第一天如果卖了第二笔,说明两买两卖,不赚钱。
核心思想:低卖高卖
思路1:贪心
var maxProfit = function(prices) {
let n = prices.length;
let min = Infinity;
let f = new Int32Array(n);
for (let i = 0; i < n; i++) {
min = Math.min(min,prices[i]);
f[i] = prices[i] - min;//最低价买入,prices[i]卖出赚的钱
}
let max = 0,ans = f[n-1],value = 0;
for (let i = n - 1; i > 0; i--) {
max = Math.max(max,prices[i]);
value = Math.max(value,max - prices[i]);// 买入prices[i],最高价卖出赚的钱
ans = Math.max(ans,value + f[i-1]);
}
return ans;
};
思路2:动态规划
function maxProfit(prices: number[]): number {
let len = prices.length;
let b1 = -prices[0], b2 = -prices[0], s1 = 0, s2 = 0;
for (let i = 1; i < len; i++) {
b1 = Math.max(b1, -prices[i]);
s1 = Math.max(s1, b1 + prices[i]);
b2 = Math.max(b2, s1 - prices[i]);
s2 = Math.max(s2, b2 + prices[i]);
}
return s2;
};
分析:其实比较之前④版本的,相当于直接默写了一遍之前学过的解法。但是因为这题的买卖次数固定为2次,
感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。
写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤