Skip to content

Commit e684f3e

Browse files
authored
Create 188._Best_Time_to_Buy_and_Sell_Stock_IV.md
1 parent a2c541c commit e684f3e

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# 188. Best Time to Buy and Sell Stock IV
2+
3+
**<font color=red>难度: Hard</font>**
4+
5+
## 刷题内容
6+
7+
> 原题连接
8+
9+
* https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/description/
10+
11+
> 内容描述
12+
13+
```
14+
Say you have an array for which the ith element is the price of a given stock on day i.
15+
16+
Design an algorithm to find the maximum profit. You may complete at most two transactions.
17+
18+
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
19+
20+
Example 1:
21+
22+
Input: [3,3,5,0,0,3,1,4]
23+
Output: 6
24+
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
25+
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
26+
Example 2:
27+
28+
Input: [1,2,3,4,5]
29+
Output: 4
30+
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
31+
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
32+
engaging multiple transactions at the same time. You must sell before buying again.
33+
Example 3:
34+
35+
Input: [7,6,4,3,1]
36+
Output: 0
37+
Explanation: In this case, no transaction is done, i.e. max profit = 0.
38+
```
39+
40+
## 解题方案
41+
42+
> 思路 1
43+
******- 时间复杂度: O(k*N^2)******- 空间复杂度: O(k*N)******
44+
45+
dp[k][i]代表在第i天完成第k次交易的最大profit
46+
47+
因此状态方程为dp[k][i] = max(dp[k][i-1], prices[i]-prices[j]+dp[k-1][j-1]),其中0 < j <= i
48+
49+
意思就是在第i天完成第k次交易的最大profit就是,在```第i-1天完成第k次交易的最大profit```
50+
```在j-1天完成前k-1次交易的最大profit(然后在第j天最后一次买入股票,并在第i天卖出)```两者中的最大值
51+
52+
另外这里还有一个trick就是当K >= len(prices)//2 的时候,实际上就跟无限次交易一样了
53+
54+
但是这样还是超时了
55+
56+
```
57+
class Solution(object):
58+
def maxProfit(self, k, prices):
59+
"""
60+
:type k: int
61+
:type prices: List[int]
62+
:rtype: int
63+
"""
64+
K = k
65+
if K >= len(prices) // 2:
66+
return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
67+
if not prices or len(prices) == 0:
68+
return 0
69+
dp = [[0] * len(prices) for i in range(K+1)]
70+
for k in range(1, K+1):
71+
for i in range(1, len(prices)):
72+
min_ = prices[0]
73+
for j in range(1, i+1):
74+
min_ = min(min_, prices[j]-dp[k-1][j-1])
75+
dp[k][i] = max(dp[k][i-1], prices[i]-min_)
76+
return dp[-1][-1]
77+
```
78+
79+
80+
> 思路 2
81+
******- 时间复杂度: O(k*N)******- 空间复杂度: O(k*N)******
82+
83+
84+
我们可以通过多加一个min_列表来记录prices[i]-prices[j]+dp[k-1][j-1],这样不用每次都重新计算1 <= j <= i的循环
85+
86+
beats 61.47%
87+
88+
```python
89+
class Solution(object):
90+
def maxProfit(self, k, prices):
91+
"""
92+
:type k: int
93+
:type prices: List[int]
94+
:rtype: int
95+
"""
96+
K = k
97+
if K >= len(prices) // 2:
98+
return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
99+
if not prices or len(prices) == 0:
100+
return 0
101+
dp, min_ = [[0] * len(prices) for i in range(K+1)], [prices[0]] * (K+1)
102+
for i in range(1, len(prices)):
103+
for k in range(1, K+1):
104+
min_[k] = min(min_[k], prices[i]-dp[k-1][i-1])
105+
dp[k][i] = max(dp[k][i-1], prices[i]-min_[k])
106+
return dp[-1][-1]
107+
```
108+
109+
110+
111+
> 思路 3
112+
******- 时间复杂度: O(k*N)******- 空间复杂度: O(k)******
113+
114+
115+
想想看,其实空间还可以压缩,那就是跟刚才思路1到思路2的改进思想一样,我们把dp[k][i]也全部记录下来,其中0 <= i <= len(prices),
116+
117+
意思就是说现在的dp[k]就等于原来的min([dp[k][i] for i in range(0, len(prices)])
118+
119+
beats 90.54%
120+
121+
```python
122+
class Solution(object):
123+
def maxProfit(self, k, prices):
124+
"""
125+
:type k: int
126+
:type prices: List[int]
127+
:rtype: int
128+
"""
129+
K = k
130+
if K >= len(prices) // 2:
131+
return sum([max(prices[i+1]-prices[i], 0) for i in range(len(prices)-1)])
132+
if not prices or len(prices) == 0:
133+
return 0
134+
dp, min_ = [0] * (K+1), [prices[0]] * (K+1)
135+
for i in range(1, len(prices)):
136+
for k in range(1, K+1):
137+
min_[k] = min(min_[k], prices[i]-dp[k-1])
138+
dp[k] = max(dp[k], prices[i]-min_[k])
139+
return dp[-1]
140+
```
141+
142+
143+
144+
145+
146+
147+
148+
149+
150+
151+
152+
153+
154+
155+
156+
157+
158+
159+
160+
161+
162+
163+

0 commit comments

Comments
 (0)