LeetCode解题 714:Best Time to Buy and Sell Stock with Transaction Fee (动态规划)
Problem 714: Best Time to Buy and Sell Stock with Transaction Fee [Medium]
Your are given an array of integers prices
, for which the i
-th element is the price of a given stock on day i
; and a non-negative integer fee representing a transaction fee
.
You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)
Return the maximum profit you can make.
Example:
Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
- Buying at prices[0] = 1
- Selling at prices[3] = 8
- Buying at prices[4] = 4
- Selling at prices[5] = 9
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
来源:LeetCode
解题思路
本题仍然需要使用动态规划思想。与题解309:Best Time to Buy and Sell Stock with Cooldown同属于最佳时机买卖股票问题。
解题思路与309题基本类似,只需要增加一项手续费,并且去掉冷却期。依旧使用maxP的状态转移方程,每天的maxP分为两种:maxP0和maxP1,分别代表当天不持有股票和当天持有股票的最大利润。第i天的maxP0可以由第i-1天的maxP0和maxP1转移,第i天的maxP1也是由第i-1天的maxP1和maxP0转移,但是由maxP0转移时,需要增加手续费。
状态转移方程为:
m
a
x
P
0
[
i
]
=
max
{
m
a
x
P
0
[
i
−
1
]
,
m
a
x
P
1
[
i
−
1
]
+
p
r
i
c
e
s
[
i
]
}
m
a
x
P
1
[
i
]
=
max
{
m
a
x
P
1
[
i
−
1
]
,
m
a
x
P
0
[
i
−
1
]
−
p
r
i
c
e
s
[
i
]
−
f
e
e
}
maxP_0[i] = \max\{maxP_0[i-1], maxP_1[i-1] + prices[i]\} \\ maxP_1[i] = \max\{maxP_1[i-1], maxP_0[i-1] - prices[i] - fee\}
maxP0[i]=max{maxP0[i−1],maxP1[i−1]+prices[i]}maxP1[i]=max{maxP1[i−1],maxP0[i−1]−prices[i]−fee}
其中,
m
a
x
P
1
[
i
−
1
]
+
p
r
i
c
e
s
[
i
]
maxP_1[i-1] + prices[i]
maxP1[i−1]+prices[i]的意思是第i-1天持有的股票在当前天卖出;
m
a
x
P
0
[
i
−
1
]
−
p
r
i
c
e
s
[
i
]
−
f
e
e
maxP_0[i-1] - prices[i] - fee
maxP0[i−1]−prices[i]−fee的意思是第i-1天之前卖出的股票在当前天买入,并且支付手续费。
由于maxP0更新只使用到前一天的maxP0和maxP1,maxP1更新也只使用到前一天的maxP1和maxP0,因此可以不使用maxP0[N]和maxP1[N]来存储,只需使用常数空间。
状态转移更新为:
m
a
x
P
0
=
max
{
m
a
x
P
0
,
m
a
x
P
1
+
p
r
i
c
e
s
[
i
]
}
m
a
x
P
1
=
max
{
m
a
x
P
1
,
p
r
e
m
a
x
P
0
−
p
r
i
c
e
s
[
i
]
−
f
e
e
}
maxP_0 = \max\{maxP_0, maxP_1 + prices[i]\} \\ maxP_1 = \max\{maxP_1, premaxP_0 - prices[i] - fee\}
maxP0=max{maxP0,maxP1+prices[i]}maxP1=max{maxP1,premaxP0−prices[i]−fee}
其中,
m
a
x
P
0
maxP_0
maxP0初始化为0,
m
a
x
P
1
maxP_1
maxP1初始化为-prices[0]-fee,
p
r
e
m
a
x
P
0
premaxP_0
premaxP0指i-1天的
m
a
x
P
0
maxP_0
maxP0。
该方法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)。
运行结果:
要点:动态规划
Solution (Java)
class Solution {
public int maxProfit(int[] prices, int fee) {
int N = prices.length;
if(N < 2) return 0;
int maxP0 = 0;
int maxP1 = -prices[0] - fee;
int pre_maxP0;
for(int i = 1; i < N; i++){
pre_maxP0 = maxP0;
maxP0 = Math.max(maxP0, maxP1 + prices[i]);
maxP1 = Math.max(maxP1, pre_maxP0 - prices[i] - fee);
}
return maxP0;
}
}