comments | difficulty | edit_url | tags | |||
---|---|---|---|---|---|---|
true |
Medium |
|
You are given an array prices
where prices[i]
is the price of a given stock on the ith
day, and an integer fee
representing a transaction fee.
Find the maximum profit you can achieve. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction.
Note:
- You may not engage in multiple transactions simultaneously (i.e., you must sell the stock before you buy again).
- The transaction fee is only charged once for each stock purchase and sale.
Example 1:
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.
Example 2:
Input: prices = [1,3,7,5,10,3], fee = 3 Output: 6
Constraints:
1 <= prices.length <= 5 * 104
1 <= prices[i] < 5 * 104
0 <= fee < 5 * 104
We design a function
The execution logic of the function
If
Otherwise, we can choose not to trade, in which case
The answer is
To avoid redundant calculations, we use memoization to record the return value of
The time complexity is
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
@cache
def dfs(i: int, j: int) -> int:
if i >= len(prices):
return 0
ans = dfs(i + 1, j)
if j:
ans = max(ans, prices[i] + dfs(i + 1, 0) - fee)
else:
ans = max(ans, -prices[i] + dfs(i + 1, 1))
return ans
return dfs(0, 0)
class Solution {
private Integer[][] f;
private int[] prices;
private int fee;
public int maxProfit(int[] prices, int fee) {
f = new Integer[prices.length][2];
this.prices = prices;
this.fee = fee;
return dfs(0, 0);
}
private int dfs(int i, int j) {
if (i >= prices.length) {
return 0;
}
if (f[i][j] != null) {
return f[i][j];
}
int ans = dfs(i + 1, j);
if (j > 0) {
ans = Math.max(ans, prices[i] + dfs(i + 1, 0) - fee);
} else {
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
}
return f[i][j] = ans;
}
}
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
int f[n][2];
memset(f, -1, sizeof(f));
function<int(int, int)> dfs = [&](int i, int j) {
if (i >= prices.size()) {
return 0;
}
if (f[i][j] != -1) {
return f[i][j];
}
int ans = dfs(i + 1, j);
if (j) {
ans = max(ans, prices[i] + dfs(i + 1, 0) - fee);
} else {
ans = max(ans, -prices[i] + dfs(i + 1, 1));
}
return f[i][j] = ans;
};
return dfs(0, 0);
}
};
func maxProfit(prices []int, fee int) int {
n := len(prices)
f := make([][2]int, n)
for i := range f {
f[i] = [2]int{-1, -1}
}
var dfs func(i, j int) int
dfs = func(i, j int) int {
if i >= n {
return 0
}
if f[i][j] != -1 {
return f[i][j]
}
ans := dfs(i+1, j)
if j > 0 {
ans = max(ans, prices[i]+dfs(i+1, 0)-fee)
} else {
ans = max(ans, -prices[i]+dfs(i+1, 1))
}
f[i][j] = ans
return ans
}
return dfs(0, 0)
}
function maxProfit(prices: number[], fee: number): number {
const n = prices.length;
const f: number[][] = Array.from({ length: n }, () => [-1, -1]);
const dfs = (i: number, j: number): number => {
if (i >= n) {
return 0;
}
if (f[i][j] !== -1) {
return f[i][j];
}
let ans = dfs(i + 1, j);
if (j) {
ans = Math.max(ans, prices[i] + dfs(i + 1, 0) - fee);
} else {
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
}
return (f[i][j] = ans);
};
return dfs(0, 0);
}
We define
When
The time complexity is
We notice that the transition of the state
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
n = len(prices)
f = [[0] * 2 for _ in range(n)]
f[0][1] = -prices[0]
for i in range(1, n):
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i] - fee)
f[i][1] = max(f[i - 1][1], f[i - 1][0] - prices[i])
return f[n - 1][0]
class Solution {
public int maxProfit(int[] prices, int fee) {
int n = prices.length;
int[][] f = new int[n][2];
f[0][1] = -prices[0];
for (int i = 1; i < n; ++i) {
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - prices[i]);
}
return f[n - 1][0];
}
}
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
int f[n][2];
memset(f, 0, sizeof(f));
f[0][1] = -prices[0];
for (int i = 1; i < n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
f[i][1] = max(f[i - 1][1], f[i - 1][0] - prices[i]);
}
return f[n - 1][0];
}
};
func maxProfit(prices []int, fee int) int {
n := len(prices)
f := make([][2]int, n)
f[0][1] = -prices[0]
for i := 1; i < n; i++ {
f[i][0] = max(f[i-1][0], f[i-1][1]+prices[i]-fee)
f[i][1] = max(f[i-1][1], f[i-1][0]-prices[i])
}
return f[n-1][0]
}
function maxProfit(prices: number[], fee: number): number {
const n = prices.length;
const f: number[][] = Array.from({ length: n }, () => [0, 0]);
f[0][1] = -prices[0];
for (let i = 1; i < n; ++i) {
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - prices[i]);
}
return f[n - 1][0];
}
class Solution:
def maxProfit(self, prices: List[int], fee: int) -> int:
f0, f1 = 0, -prices[0]
for x in prices[1:]:
f0, f1 = max(f0, f1 + x - fee), max(f1, f0 - x)
return f0
class Solution {
public int maxProfit(int[] prices, int fee) {
int f0 = 0, f1 = -prices[0];
for (int i = 1; i < prices.length; ++i) {
int g0 = Math.max(f0, f1 + prices[i] - fee);
f1 = Math.max(f1, f0 - prices[i]);
f0 = g0;
}
return f0;
}
}
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int f0 = 0, f1 = -prices[0];
for (int i = 1; i < prices.size(); ++i) {
int g0 = max(f0, f1 + prices[i] - fee);
f1 = max(f1, f0 - prices[i]);
f0 = g0;
}
return f0;
}
};
func maxProfit(prices []int, fee int) int {
f0, f1 := 0, -prices[0]
for _, x := range prices[1:] {
f0, f1 = max(f0, f1+x-fee), max(f1, f0-x)
}
return f0
}
function maxProfit(prices: number[], fee: number): number {
const n = prices.length;
let [f0, f1] = [0, -prices[0]];
for (const x of prices.slice(1)) {
[f0, f1] = [Math.max(f0, f1 + x - fee), Math.max(f1, f0 - x)];
}
return f0;
}