Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 825a125

Browse files
feat: add solutions to lc problem: No.0714 (#1746)
No.0714.Best Time to Buy and Sell Stock with Transaction Fee
1 parent 9f04133 commit 825a125

File tree

7 files changed

+569
-75
lines changed

7 files changed

+569
-75
lines changed

‎solution/0700-0799/0714.Best Time to Buy and Sell Stock with Transaction Fee/README.md‎

Lines changed: 261 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,31 @@
4949

5050
<!-- 这里可写通用的实现逻辑 -->
5151

52-
动态规划法。
52+
**方法一:记忆化搜索**
5353

54-
设 f1 表示当天持有股票的最大利润,f2 表示当天没持有股票的最大利润
54+
我们设计一个函数 $dfs(i, j),ドル表示从第 $i$ 天开始,状态为 $j$ 时,能够获得的最大利润。其中 $j$ 的取值为 0,ドル 1,ドル分别表示当前不持有股票和持有股票。答案即为 $dfs(0, 0)$
5555

56-
初始第 1 天结束时,`f1 = -prices[0]`,`f2 = 0`
56+
函数 $dfs(i, j)$ 的执行逻辑如下:
5757

58-
从第 2 天开始,当天结束时:
58+
如果 $i \geq n,ドル那么没有股票可以交易了,此时返回 0ドル$;
5959

60-
- 若持有,则可能是前一天持有,今天继续持有;也可能前一天没持有,今天买入,`f1 = max(f1, f2 - price)`
61-
- 若没持有,则可能是前一天持有,今天卖出;也可能是前一天没没有,今天继续没持有,`f2 = max(f2, f1 + price - fee)`
60+
否则,我们可以选择不交易,此时 $dfs(i, j) = dfs(i + 1, j)$。我们也可以进行股票交易,如果此时 $j \gt 0,ドル说明当前持有股票,可以卖出,此时 $dfs(i, j) = prices[i] + dfs(i + 1, 0) - fee$;如果此时 $j = 0,ドル说明当前不持有股票,可以买入,此时 $dfs(i, j) = -prices[i] + dfs(i + 1, 1)$。取最大值作为函数 $dfs(i, j)$ 的返回值。
6261

63-
最后返回 f2 即可。
62+
答案为 $dfs(0, 0)$。
63+
64+
为了避免重复计算,我们使用记忆化搜索的方法,用一个数组 $f$ 记录 $dfs(i, j)$ 的返回值,如果 $f[i][j]$ 不为 $-1,ドル说明已经计算过,直接返回 $f[i][j]$ 即可。
65+
66+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $prices$ 的长度。
67+
68+
**方法二:动态规划**
69+
70+
我们定义 $f[i][j]$ 表示到第 $i$ 天,且状态为 $j$ 时,能够获得的最大利润。其中 $j$ 的取值为 0,ドル 1,ドル分别表示当前不持有股票和持有股票。初始时 $f[0][0] = 0,ドル $f[0][1] = -prices[0]$。
71+
72+
当 $i \geq 1$ 时,如果当前不持有股票,那么 $f[i][0]$ 可以由 $f[i - 1][0]$ 和 $f[i - 1][1] + prices[i] - fee$ 转移得到,即 $f[i][0] = \max(f[i - 1][0], f[i - 1][1] + prices[i] - fee)$;如果当前持有股票,那么 $f[i][1]$ 可以由 $f[i - 1][1]$ 和 $f[i - 1][0] - prices[i]$ 转移得到,即 $f[i][1] = \max(f[i - 1][1], f[i - 1][0] - prices[i])$。最终答案为 $f[n - 1][0]$。
73+
74+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。其中 $n$ 为数组 $prices$ 的长度。
75+
76+
我们注意到,状态 $f[i][]$ 的转移只与 $f[i - 1][]$ 和 $f[i - 1][]$ 有关,因此我们可以用两个变量 $f_0, f_1$ 代替数组 $f,ドル将空间复杂度优化到 $O(1)$。
6477

6578
<!-- tabs:start -->
6679

@@ -71,12 +84,39 @@
7184
```python
7285
class Solution:
7386
def maxProfit(self, prices: List[int], fee: int) -> int:
74-
# 持有,没持有
75-
f1, f2 = -prices[0], 0
76-
for price in prices[1:]:
77-
f1 = max(f1, f2 - price)
78-
f2 = max(f2, f1 + price - fee)
79-
return f2
87+
@cache
88+
def dfs(i: int, j: int) -> int:
89+
if i >= len(prices):
90+
return 0
91+
ans = dfs(i + 1, j)
92+
if j:
93+
ans = max(ans, prices[i] + dfs(i + 1, 0) - fee)
94+
else:
95+
ans = max(ans, -prices[i] + dfs(i + 1, 1))
96+
return ans
97+
98+
return dfs(0, 0)
99+
```
100+
101+
```python
102+
class Solution:
103+
def maxProfit(self, prices: List[int], fee: int) -> int:
104+
n = len(prices)
105+
f = [[0] * 2 for _ in range(n)]
106+
f[0][1] = -prices[0]
107+
for i in range(1, n):
108+
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i] - fee)
109+
f[i][1] = max(f[i - 1][1], f[i - 1][0] - prices[i])
110+
return f[n - 1][0]
111+
```
112+
113+
```python
114+
class Solution:
115+
def maxProfit(self, prices: List[int], fee: int) -> int:
116+
f0, f1 = 0, -prices[0]
117+
for x in prices[1:]:
118+
f0, f1 = max(f0, f1 + x - fee), max(f1, f0 - x)
119+
return f0
80120
```
81121

82122
### **Java**
@@ -85,13 +125,60 @@ class Solution:
85125

86126
```java
87127
class Solution {
128+
private Integer[][] f;
129+
private int[] prices;
130+
private int fee;
131+
88132
public int maxProfit(int[] prices, int fee) {
89-
int f1 = -prices[0], f2 = 0;
133+
f = new Integer[prices.length][2];
134+
this.prices = prices;
135+
this.fee = fee;
136+
return dfs(0, 0);
137+
}
138+
139+
private int dfs(int i, int j) {
140+
if (i >= prices.length) {
141+
return 0;
142+
}
143+
if (f[i][j] != null) {
144+
return f[i][j];
145+
}
146+
int ans = dfs(i + 1, j);
147+
if (j > 0) {
148+
ans = Math.max(ans, prices[i] + dfs(i + 1, 0) - fee);
149+
} else {
150+
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
151+
}
152+
return f[i][j] = ans;
153+
}
154+
}
155+
```
156+
157+
```java
158+
class Solution {
159+
public int maxProfit(int[] prices, int fee) {
160+
int n = prices.length;
161+
int[][] f = new int[n][2];
162+
f[0][1] = -prices[0];
163+
for (int i = 1; i < n; ++i) {
164+
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
165+
f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - prices[i]);
166+
}
167+
return f[n - 1][0];
168+
}
169+
}
170+
```
171+
172+
```java
173+
class Solution {
174+
public int maxProfit(int[] prices, int fee) {
175+
int f0 = 0, f1 = -prices[0];
90176
for (int i = 1; i < prices.length; ++i) {
91-
f1 = Math.max(f1, f2 - prices[i]);
92-
f2 = Math.max(f2, f1 + prices[i] - fee);
177+
int g0 = Math.max(f0, f1 + prices[i] - fee);
178+
f1 = Math.max(f1, f0 - prices[i]);
179+
f0 = g0;
93180
}
94-
return f2;
181+
return f0;
95182
}
96183
}
97184
```
@@ -102,12 +189,57 @@ class Solution {
102189
class Solution {
103190
public:
104191
int maxProfit(vector<int>& prices, int fee) {
105-
int f1 = -prices[0], f2 = 0;
192+
int n = prices.size();
193+
int f[n][2];
194+
memset(f, -1, sizeof(f));
195+
function<int(int, int)> dfs = [&](int i, int j) {
196+
if (i >= prices.size()) {
197+
return 0;
198+
}
199+
if (f[i][j] != -1) {
200+
return f[i][j];
201+
}
202+
int ans = dfs(i + 1, j);
203+
if (j) {
204+
ans = max(ans, prices[i] + dfs(i + 1, 0) - fee);
205+
} else {
206+
ans = max(ans, -prices[i] + dfs(i + 1, 1));
207+
}
208+
return f[i][j] = ans;
209+
};
210+
return dfs(0, 0);
211+
}
212+
};
213+
```
214+
215+
```cpp
216+
class Solution {
217+
public:
218+
int maxProfit(vector<int>& prices, int fee) {
219+
int n = prices.size();
220+
int f[n][2];
221+
memset(f, 0, sizeof(f));
222+
f[0][1] = -prices[0];
223+
for (int i = 1; i < n; ++i) {
224+
f[i][0] = max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
225+
f[i][1] = max(f[i - 1][1], f[i - 1][0] - prices[i]);
226+
}
227+
return f[n - 1][0];
228+
}
229+
};
230+
```
231+
232+
```cpp
233+
class Solution {
234+
public:
235+
int maxProfit(vector<int>& prices, int fee) {
236+
int f0 = 0, f1 = -prices[0];
106237
for (int i = 1; i < prices.size(); ++i) {
107-
f1 = max(f1, f2 - prices[i]);
108-
f2 = max(f2, f1 + prices[i] - fee);
238+
int g0 = max(f0, f1 + prices[i] - fee);
239+
f1 = max(f1, f0 - prices[i]);
240+
f0 = g0;
109241
}
110-
return f2;
242+
return f0;
111243
}
112244
};
113245
```
@@ -116,12 +248,66 @@ public:
116248
117249
```go
118250
func maxProfit(prices []int, fee int) int {
119-
f1, f2 := -prices[0], 0
120-
for i := 1; i < len(prices); i++ {
121-
f1 = max(f1, f2-prices[i])
122-
f2 = max(f2, f1+prices[i]-fee)
251+
n := len(prices)
252+
f := make([][2]int, n)
253+
for i := range f {
254+
f[i] = [2]int{-1, -1}
255+
}
256+
var dfs func(i, j int) int
257+
dfs = func(i, j int) int {
258+
if i >= n {
259+
return 0
260+
}
261+
if f[i][j] != -1 {
262+
return f[i][j]
263+
}
264+
ans := dfs(i+1, j)
265+
if j > 0 {
266+
ans = max(ans, prices[i]+dfs(i+1, 0)-fee)
267+
} else {
268+
ans = max(ans, -prices[i]+dfs(i+1, 1))
269+
}
270+
f[i][j] = ans
271+
return ans
272+
}
273+
return dfs(0, 0)
274+
}
275+
276+
func max(a, b int) int {
277+
if a > b {
278+
return a
279+
}
280+
return b
281+
}
282+
```
283+
284+
```go
285+
func maxProfit(prices []int, fee int) int {
286+
n := len(prices)
287+
f := make([][2]int, n)
288+
f[0][1] = -prices[0]
289+
for i := 1; i < n; i++ {
290+
f[i][0] = max(f[i-1][0], f[i-1][1]+prices[i]-fee)
291+
f[i][1] = max(f[i-1][1], f[i-1][0]-prices[i])
292+
}
293+
return f[n-1][0]
294+
}
295+
296+
func max(a, b int) int {
297+
if a > b {
298+
return a
299+
}
300+
return b
301+
}
302+
```
303+
304+
```go
305+
func maxProfit(prices []int, fee int) int {
306+
f0, f1 := 0, -prices[0]
307+
for _, x := range prices[1:] {
308+
f0, f1 = max(f0, f1+x-fee), max(f1, f0-x)
123309
}
124-
return f2
310+
return f0
125311
}
126312

127313
func max(a, b int) int {
@@ -132,6 +318,55 @@ func max(a, b int) int {
132318
}
133319
```
134320

321+
### **TypeScript**
322+
323+
```ts
324+
function maxProfit(prices: number[], fee: number): number {
325+
const n = prices.length;
326+
const f: number[][] = Array.from({ length: n }, () => [-1, -1]);
327+
const dfs = (i: number, j: number): number => {
328+
if (i >= n) {
329+
return 0;
330+
}
331+
if (f[i][j] !== -1) {
332+
return f[i][j];
333+
}
334+
let ans = dfs(i + 1, j);
335+
if (j) {
336+
ans = Math.max(ans, prices[i] + dfs(i + 1, 0) - fee);
337+
} else {
338+
ans = Math.max(ans, -prices[i] + dfs(i + 1, 1));
339+
}
340+
return (f[i][j] = ans);
341+
};
342+
return dfs(0, 0);
343+
}
344+
```
345+
346+
```ts
347+
function maxProfit(prices: number[], fee: number): number {
348+
const n = prices.length;
349+
const f: number[][] = Array.from({ length: n }, () => [0, 0]);
350+
f[0][1] = -prices[0];
351+
for (let i = 1; i < n; ++i) {
352+
f[i][0] = Math.max(f[i - 1][0], f[i - 1][1] + prices[i] - fee);
353+
f[i][1] = Math.max(f[i - 1][1], f[i - 1][0] - prices[i]);
354+
}
355+
return f[n - 1][0];
356+
}
357+
```
358+
359+
```ts
360+
function maxProfit(prices: number[], fee: number): number {
361+
const n = prices.length;
362+
let [f0, f1] = [0, -prices[0]];
363+
for (const x of prices.slice(1)) {
364+
[f0, f1] = [Math.max(f0, f1 + x - fee), Math.max(f1, f0 - x)];
365+
}
366+
return f0;
367+
}
368+
```
369+
135370
### **...**
136371

137372
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /