这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
99. 买卖股票的最佳时机 IV (best-time-to-buy-and-sell-stock-iv)
标签
- 转化思维
- 困难
题目
给定一个整数数组 prices ,它的第 i 个元素 prices[i]
是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k
笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
输入:k = 2, prices = [3,2,6,5,0,3]
输出:7
解释:在第 2 天 (股票价格 = 2) 的时候买入,
在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。
随后,在第 5 天 (股票价格 = 0) 的时候买入,
在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
基本思想
这题根上题不同之处在于,上题固定 2
次交易,这次是传入的 k
次
上次状态有 2个买点 和 2个卖点
,那么这次就有 k个买点 和 k个卖点
所以我们可以设置两个数组来分别代替 当天最大收益
的买卖情况
- [buy1, buy2, buy3....buyk]
- [cell1, cell2, cell3....cellk]
接下来几乎和上面问题相同做出状态转移就行了。如何转移? 保证每天都收益最大
即可。
状态转移方程:
buy[j] = Math.max(buy[j], sell[j-1] - prices[i])
sell[j] = Math.max(sell[j], buy[j] + prices[i])
写法实现
var maxProfit = function(k, prices) {
// 如果 k 超过半数,也是等于无效,取半数 或者 k 作为交易次数
k = Math.min(k, Math.floor(prices.length / 2))
let buy = new Array(k+1).fill(-Infinity)
let sell = new Array(k+1).fill(0)
for (let i = 0; i < prices.length; i++) {
for (let j = 1; j < k+1; j++) {
buy[j] = Math.max(buy[j], sell[j-1] - prices[i])
sell[j] = Math.max(sell[j], buy[j] + prices[i])
}
}
return sell.pop()
};
let k = 2, prices = [3,2,6,5,0,3]
console.log(maxProfit(k, prices))
100. 最佳买卖股票时机含冷冻期 (best-time-to-buy-and-sell-stock-with-cooldown)
标签
- 转化思路
- 困难
题目
这里不贴题了,leetcode打开就行,题目大意:
给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)。
输入: [1,2,3,0,2]
输出: 3
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
基本思想
由于有冷冻期,因此在任意一天结束之后,我们会处于以下3个状态中的一种:
- 手中没持有,可以买
- 手中持有,可以卖
- 冷冻期,手中没持有,买不了
我们的目标是最大化收益
,跟上题类似,我们分别将它们当前的最大利润记为buy sell sellPre
buy
是最佳买入的状态,sell
是最佳卖出的状态,sellPre
是前一次卖出的状态。
写法实现
var maxProfit = function(prices) {
let [buy, sell, sellPre] = [-Infinity, 0, 0]
for (let i = 0; i < prices.length; i++) {
buy = Math.max(buy, sellPre - prices[i])
sellPre = sell
sell = Math.max(sell, buy + prices[i])
}
return sell
};
let prices = [1,2,3,0,2]
console.log(maxProfit(prices))
纪念下,正好100题,不过路才刚刚开始!
路漫漫其修远兮 吾将上下而求索
另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦
搜索我的微信号infinity_9368
,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文
,验证消息请发给我
presious tower shock the rever monster
,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧