前端算法面试必刷题系列[52]

217 阅读2分钟

这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。

99. 买卖股票的最佳时机 IV (best-time-to-buy-and-sell-stock-iv)

标签

  • 转化思维
  • 困难

题目

leetcode 传送门

给定一个整数数组 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 传送门

这里不贴题了,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,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考