买卖股票的最佳时机 II
题目
给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例1:
输入: [7,1,5,3,6,4] 输出: 7 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例2:
输入: [1,2,3,4,5] 输出: 4 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例3:
输入: [7,6,4,3,1] 输出: 0 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
穷举法
罗列所有的买卖组合,再计算其中利润最大的组合。多次买卖由第一次买卖和后续买卖组成,后续买卖只能在第一次卖出点之后发生。用树表示所有买卖组合,第一层为可选的第一次买卖组合(根节点为第零层,同一天买卖等同于当天不买卖),第N层为第N次买卖。
举个例子,给定价格序列[7, 1, 5, 3, 6, 4]
。第一次买卖有六种选择:
- 以7的价格买入,以7的价格卖出。等同于第一天不买卖。
- 以7的价格买入,以1的价格卖出。
- 以7的价格买入,以5的价格卖出。
- 以7的价格买入,以3的价格卖出。
- 以7的价格买入,以6的价格卖出。
- 以7的价格买入,以4的价格卖出。
第二次买卖可行的选择由第一次买卖决定。第二次买卖的买入点一定是第一次买卖的卖出点后一天。依此类推。
代码
首先,在第一天买进,罗列出所有的卖出选择 包括当天卖出。
然后,罗列出在剩余价格序列中的买卖序列组合。剩余价格序列由这一次卖出点决定。所以不同的当次买卖产生不同的剩余价格序列,也产了不同的剩余买卖序列组合。
再然后,组合当次买卖与剩余买卖序列组合,构成新的买卖序列组合。
最后,合计所有的买卖序列产生的利润,从中取最大值。
复杂度分析
时间复杂度
时间复杂度为:
空间复杂度
空间复杂度等于树的最大深度,为
贪婪算法
在第一天买入,如果利润持续增加(第二天的价格大于今天)则持有。若利润下降(第二天价格低于当天)则卖出。(可同一天买卖,等同于当天不交易)。然后,在剩余价格序列中重复相同的操作。
举个例子,给定价格序列[7, 1, 5, 3, 6, 4]
。
- 第一次,在7买入,在7卖出。等同于不交易。剩余价格序列
[1, 5, 3, 6, 4]
- 第二次,在1买入,在5卖出。剩余价格序列
[3, 6, 4]
- 第三次,在3买入,在6卖出。剩余价格序列
[4]
- 第四次,在4买入,在4卖出。等同于交易。
代码
首先,在第一天买入,在利润开始下降前卖出(同天买卖等同于不交易)。得到利润和剩余价格序列(这𥚃用剩余价格序列开始下标)。
然后,如果剩余价格列表不空,则继续在第一天(剩余序列中的第一天)买入,在利润开始下降前卖出。得到利润和剩余价格序列。
在第一天买入,如果价格在上升意味着利润增加,应继续持有。如果价格下降则意味着利润下降,应在价格下降前卖出。
复杂度分析
时间复杂度
时间复杂度等于profit
被调用的次数及每次profit
中遍历价格序列的长度,其等于整个价格序列的长度。所以,时间复杂度为:
空间复杂度
只有三毎变量maxProfit
, remainStart
和profit
。