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. Linux 挂载 NFS

    NFS(网络文件系统),这是在 Linux 系统上常用的文件共享方式.也可以做为作为一个远程存储使用,比如:我有个网站,用户可以上传文件,但文件慢慢会越来越多,这个时候我们只能把存放上传文件的目录挂在 ...

  2. git merge 和 git rebase 小结

    Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 ---------------------- ...

  3. [转] Memcached参数设置 命令

    只是看到了..这些命令肯定是没问题的.. 笔者现在也还不会用..汗..先留着..找到怎么用了在回来修改.. memcached的基本设置: -p 监听的端口-l 连接的IP地址, 默认是本机-d st ...

  4. jquery 中的事件冒泡

    废话少说,先来一段代码热热身: <!DOCTYPE html> <html> <head> <title>demo</title> < ...

  5. asp.net webform中使用async,await实现异步操作

    摘要 最近想着将项目中的部分耗时的操作,进行异步化.就自己弄个demo进行学习.只需下面几个步骤就可以将aspx页面中注册异步操作. demo 比如我们需要抓取某个url的内容,这个时候我们可能会有下 ...

  6. 【9-7】XML学习笔记01

    Tips XML标签大小写敏感: XML文件一般使用国际化通用的编码“utf-8”,所以平时看到的XML文件的头部都会有这样的代码: <?xml version="1.0" ...

  7. 如何让图片在垂直方向与 div的底部对齐 水平居中

    需要图片的绝对定位postion: absolute. 一般定位时, 是用div去定位. 一般不直接用 非div去"绝对/相对"定位. 如不直接用 等去定位. 因为这些好像不好定位 ...

  8. CF460D Little Victor and Set (找规律)

    D - Little Victor and Set Codeforces Round #262 (Div. 2) D D. Little Victor and Set time limit per t ...

  9. C#委托全解析

    什么是委托?                                                                                       委托类似于C语 ...

  10. cf306 C. Divisibility by Eight(数学推导)

    C. Divisibility by Eight time limit per test 2 seconds memory limit per test 256 megabytes input sta ...