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) with the following restrictions:

  • You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
  • After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day)

Example:

prices = [1, 2, 3, 0, 2]
maxProfit = 3
transactions = [buy, sell, cooldown, buy, sell] 分析:

因为当前的选择对后面的选择会产生影响,我们可以倒着来分析。

我们用maximumProfit[i]来表示从i 到 length - 1 可以获取的最大profit. 怎么计算maximumProfit[i]呢?那么对于i来讲,最坏情况是maximumProfit[i] = maximumProfit[i + 1].

然后我们把price[i]作为当前最低价,如果后面发现更高的价格price[j],我们就做出更新。

if (j < length - 2) {
  maximumProfit[i] = Math.max(prices[j] - low + maximumProfit[j + 2], maximumProfit[i]);
} else {
  maximumProfit[i] = Math.max(prices[j] - low, maximumProfit[i]);
}

 public int maxProfit(int[] prices) {
if (prices == null || prices.length <= )
return ; int length = prices.length;
int[] maximumProfit = new int[length];
maximumProfit[length - ] = ;
maximumProfit[length - ] = Math.max(, prices[length - ] - prices[length - ]); for (int i = length - ; i >= ; i--) {
maximumProfit[i] = maximumProfit[i + ];
int low = prices[i];
for (int j = i + ; j < length; j++) {
if (prices[j] > low) {
if (j < length - ) {
maximumProfit[i] = Math.max(prices[j] - low + maximumProfit[j + ], maximumProfit[i]);
} else {
maximumProfit[i] = Math.max(prices[j] - low, maximumProfit[i]);
}
} else {
low = prices[j];
}
}
}
return maximumProfit[];
}

很明显,时间总复杂度为O(n^2).

另一个方法:

Analysis: https://discuss.leetcode.com/topic/30431/easiest-java-solution-with-explanations

1. Define States

To represent the decision at index i:

  • buy[i]: Max profit till index i. The series of transaction is ending with a buy.
  • sell[i]: Max profit till index i. The series of transaction is ending with a sell.

To clarify:

  • Till index i, the buy / sell action must happen and must be the last action. It may not happen at index i. It may happen at i - 1, i - 2, ... 0.
  • In the end n - 1, return sell[n - 1]. Apparently we cannot finally end up with a buy. In that case, we would rather take a rest at n - 1.
  • For special case no transaction at all, classify it as sell[i], so that in the end, we can still return sell[n - 1]. Thanks @alex153 @kennethliaoke @anshu2.

2. Define Recursion

  • buy[i]: To make a decision whether to buy at i, we either take a rest, by just using the old decision at i - 1, or sell at/beforei - 2, then buy at i, We cannot sell at i - 1, then buy at i, because of cooldown.
  • sell[i]: To make a decision whether to sell at i, we either take a rest, by just using the old decision at i - 1, or buy at/before i - 1, then sell at i.

So we get the following formula:

buy[i] = Math.max(buy[i - 1], sell[i - 2] - prices[i]);
sell[i] = Math.max(sell[i - 1], buy[i - 1] + prices[i]);

3. Optimize to O(1) Space

DP solution only depending on i - 1 and i - 2 can be optimized using O(1) space.

  • Let b2, b1, b0 represent buy[i - 2], buy[i - 1], buy[i]
  • Let s2, s1, s0 represent sell[i - 2], sell[i - 1], sell[i]

Then arrays turn into Fibonacci like recursion:

b0 = Math.max(b1, s2 - prices[i]);
s0 = Math.max(s1, b1 + prices[i]);

4. Write Code in 5 Minutes

First we define the initial states at i = 0:

  • We can buy. The max profit at i = 0 ending with a buy is -prices[0].
  • We cannot sell. The max profit at i = 0 ending with a sell is 0.
 public int maxProfit(int[] prices) {
if(prices == null || prices.length <= ) return ; int b0 = -prices[], b1 = b0;
int s0 = , s1 = , s2 = ; for(int i = ; i < prices.length; i++) {
b0 = Math.max(b1, s2 - prices[i]);
s0 = Math.max(s1, b1 + prices[i]);
b1 = b0; s2 = s1; s1 = s0;
}
return s0;
}

Best Time to Buy and Sell Stock with Cooldown的更多相关文章

  1. leetcode 121. Best Time to Buy and Sell Stock 、122.Best Time to Buy and Sell Stock II 、309. Best Time to Buy and Sell Stock with Cooldown

    121. Best Time to Buy and Sell Stock 题目的要求是只买卖一次,买的价格越低,卖的价格越高,肯定收益就越大 遍历整个数组,维护一个当前位置之前最低的买入价格,然后每次 ...

  2. Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown)

    Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown) 股票问题: 121. 买卖股票 ...

  3. [LeetCode] Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  4. [LeetCode] 309. Best Time to Buy and Sell Stock with Cooldown 买卖股票的最佳时间有冷却期

    Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...

  5. 【LeetCode】309. Best Time to Buy and Sell Stock with Cooldown 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 动态规划 日期 题目地址:https://leetc ...

  6. LeetCode Best Time to Buy and Sell Stock with Cooldown

    原题链接在这里:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 题目: Say you hav ...

  7. 121. 122. 123. 188. Best Time to Buy and Sell Stock *HARD* 309. Best Time to Buy and Sell Stock with Cooldown -- 买卖股票

    121. Say you have an array for which the ith element is the price of a given stock on day i. If you ...

  8. 309. Best Time to Buy and Sell Stock with Cooldown

    题目: Say you have an array for which the ith element is the price of a given stock on day i. Design a ...

  9. 解题报告Best Time to Buy and Sell Stock with Cooldown

    题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...

随机推荐

  1. JSP-Servlet的工作流程

    Servlet基础 1.Servlet概述 JSP的前身就是Servlet.Servlet就是在服务器端运行的一段小程序.一个Servlet就是一个Java类,并且可以通过“请求-响应”编程模型来访问 ...

  2. Linux下删除命令

    linux删除目录很简单 使用rm -rf命令即可.直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目录名字(警告:不作任何提示,且不可恢复,不要说没提醒哦!严重警告!!!)-r 就是向下 ...

  3. Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件

    第二条:类的头文件中尽量少引入其他头文件 使用向前声明(forward declaring) @class EOCEmployer 1, 将引入头文件的实际尽量延后,只在确有需要时才引入,这样就可以减 ...

  4. js其它

    1.js的数组           * 什么是数组?                        - 使用变量,var m = 10;                        - java里面 ...

  5. Java Programming Test Question 4

    What will be the boolean flag value to reach the finally block? public class JPTQuestion4 { public s ...

  6. winxp可以禁用的服务

    要注意的是: 虽然某个服务你设置成了手动, 而且在services.msc中好像也没有启动, 但是并不表示这个服务不可以被启动 因为某些软件, 可能在程序内部进行了编程的设置, 它可以在内部去启动 服 ...

  7. 从Google开源RE2库学习到的C++测试方案

    最近因为科研需求,一直在研究Google的开源RE2库(正则表达式识别库),库源码体积庞大,用C++写的,对于我这个以前专供Java的人来说真的是一件很痛苦的事,每天只能啃一点点.今天研究了下里面用到 ...

  8. 密码学初级教程(一)基本概念及DES加密算法

    密码技术在网络通信中广泛使用,本节是初步接触密码学技术的笔记. 第1章 加密-解密 破译 明文-密文 密钥 密码算法 对称密码-公钥密码(非对称密码) 单向散列函数-散列值 消息认证码 数字签名 伪随 ...

  9. mybaties # , $

    mybaties会对#引入的值加上双引号, 如: #{buildingName} -------->"buildingName";mybaties会将$引入的值直接显示到sq ...

  10. 一张图告诉你,只会JavaScript还不够!

    会了JavaScript语法,你就真的会了JavaScript吗,来看这张图!是超实用的JavaScript代码段一书的导览!熊孩子们,赶紧学习去吧!