Skip to content

Commit cacb7b6

Browse files
committed
opt stock problems
1 parent 31bd133 commit cacb7b6

File tree

60 files changed

+2107
-790
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+2107
-790
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ node_modules/
2121
.env.yml
2222
/python
2323
package-lock.json
24+
.hugo_build.lock

.prettierrc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"overrides": [
3+
{
4+
"files": ".prettierrc",
5+
"options": { "parser": "json" }
6+
},
7+
{
8+
"files": ["*.md"],
9+
"options": {
10+
"tabWidth": 2
11+
}
12+
}
13+
]
14+
}

content/zh/docs/jzof/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
weight: 1
2+
weight: 11
33
bookFlatSection: true
44
title: "剑指 Offer"
55
---
File renamed without changes.
File renamed without changes.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
weight: 1
3-
title: "0000-0099"
3+
title: "0001-0100"
44
bookCollapseSection: true
55
---
66

7-
# 0000-0099
7+
# 0001-0100

content/zh/docs/leetcode/0100-0199/0100.md

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
weight: 21
3+
bookFlatSection: true
4+
title: "121.买卖股票的最佳时机"
5+
description: "121.买卖股票的最佳时机"
6+
---
7+
8+
# 121.买卖股票的最佳时机
9+
10+
{{< hint danger >}}
11+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[Awesome Golang Algorithm](https://github.com/kylesliu/awesome-golang-algorithm)
12+
{{< /hint >}}
13+
14+
## 题目描述
15+
16+
{{< button href="https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/" >}}题目地址{{< /button >}}
17+
{{< button href="https://github.com/kylesliu/awesome-golang-algorithm/tree/master/leetcode/101-200/0121.Best-Time-to-Buy-and-Sell-Stock" >}}代码{{< /button >}}
18+
19+
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
20+
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
21+
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
22+
23+
{{< hint info >}}
24+
**提示**
25+
26+
只能卖一次股票
27+
{{< /hint >}}
28+
29+
### **示例 1**
30+
31+
```text
32+
输入:[7,1,5,3,6,4]
33+
输出:5
34+
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
35+
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
36+
```
37+
38+
### **示例 2**
39+
40+
```text
41+
输入:prices = [7,6,4,3,1]
42+
输出:0
43+
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
44+
```
45+
46+
### **限制**
47+
48+
- 1 <= prices.length <= 105
49+
- 0 <= prices[i] <= 104
50+
51+
## 题解
52+
53+
我们需要找出给定数组中两个数字之间的最大差值(即,最大利润)。此外,第二个数字(卖出价格)必须大于第一个数字(买入价格)。形式上,对于每组 `i``j`(其中 `j > i`)我们需要找出 {{< katex >}}\max(prices[j]−prices[i]){{< /katex >}}。
54+
55+
### 思路 1:**暴力循环**
56+
57+
**算法流程:**
58+
59+
2 次循环分别找出最大价格和最小价格
60+
61+
**复杂度分析:**
62+
63+
- **时间复杂度:** {{< katex >}}\Omicron(N^{2}){{< /katex >}} , 循环运行 {{< katex >}}\cfrac{n (n-1)}{2}{{< /katex >}} 次。
64+
- **空间复杂度:** {{< katex >}}\Omicron(1){{< /katex >}} , 只使用了常数个变量。
65+
66+
#### 代码
67+
68+
{{< tabs "lc121-01" >}}
69+
{{< tab "Go" >}}
70+
71+
```go
72+
func maxProfit_1(prices []int) int {
73+
ans := 0
74+
for i := 0; i < len(prices); i++ {
75+
for j := i + 1; j < len(prices); j++ {
76+
ans = max(ans, prices[j]-prices[i])
77+
}
78+
}
79+
return ans
80+
}
81+
```
82+
83+
{{< /tab >}}
84+
{{< /tabs >}}
85+
86+
### 思路 2:**贪心**
87+
88+
#### 算法流程
89+
90+
![leetcode_121_2](https://s.gin.sh/blog/leetcode/leetcode_121_2.png)
91+
92+
因为股票就买卖一次,那么贪心的想法很自然就是取最左最小值,取最右最大值,那么得到的差值就是最大利润。
93+
94+
#### 复杂度分析
95+
96+
- **时间复杂度:** {{< katex >}}\Omicron(N){{< /katex >}}
97+
- **空间复杂度:** {{< katex >}}\Omicron(1){{< /katex >}}
98+
99+
{{< tabs "lc121-02" >}}
100+
{{< tab "Go" >}}
101+
102+
```go
103+
func maxProfit_2(prices []int) int {
104+
ans, lowPrice := 0, prices[0]
105+
for i := 0; i < len(prices); i++ {
106+
ans = max(ans, prices[i]-lowPrice)
107+
lowPrice = min(lowPrice, prices[i])
108+
}
109+
return ans
110+
}
111+
```
112+
113+
{{< /tab >}}
114+
{{< /tabs >}}
115+
116+
### 思路 3:**动态规划**
117+
118+
#### 算法流程
119+
120+
- 确定 dp 数组(Dynamic Planning)以及下标的含义:
121+
122+
<!-- prettier-ignore -->
123+
{{< katex display >}}
124+
\begin{dcases}
125+
dp[i][0] & 第 i 天持有股票所得最多现金
126+
\\
127+
dp[i][1] & 第 i 天不持有股票所得最多现金
128+
\end{dcases}
129+
{{< /katex >}}
130+
131+
- 确定递推公式
132+
133+
<!-- prettier-ignore -->
134+
{{< mermaid >}}
135+
flowchart LR
136+
A[第 i 天是否持有股票] -->|持有| B(第 i-1 天是否持有股票)
137+
A[第 i 天是否持有股票] -->|未持有| C(第 i-1 天是否持有股票)
138+
B -->|持有| D["保存不动:dp[i - 1][0]"]
139+
B -->|未持有| E["购买股票:-prices[i]"]
140+
C -->|持有| F["保存不动:dp[i - 1][1]"]
141+
C -->|未持有| G["购买股票:prices[i] + dp[i - 1][0]"]
142+
{{< /mermaid >}}
143+
144+
<!-- prettier-ignore -->
145+
{{< katex display >}}
146+
\begin{dcases}
147+
dp[i][0] = \max(dp[i-1][0], -prices[i])
148+
\\
149+
dp[i][1] = \max(dp[i-1][1], dp[i-1][0]+prices[i])
150+
\end{dcases}
151+
{{< /katex >}}
152+
153+
- dp 数组如何初始化
154+
155+
<!-- prettier-ignore -->
156+
{{< katex display >}}
157+
\begin{dcases}
158+
dp[0][0] = -prices[0]
159+
\\
160+
dp[0][1] = 0
161+
\end{dcases}
162+
{{< /katex >}}
163+
164+
- 确定遍历顺序
165+
166+
<!-- prettier-ignore -->
167+
{{< katex display >}}
168+
\int_{prices_i}\ 1<=i<len(prices)-1
169+
{{< /katex >}}
170+
171+
- 举例推导 dp 数组,输入:`[7,1,5,3,6,4]`
172+
173+
<!-- prettier-ignore -->
174+
{{< katex display>}}
175+
\begin{bmatrix}
176+
i & dp[i][0] & dp[i][1] \\
177+
0 & -7 & 0 \\
178+
1 & -1 & 0 \\
179+
2 & -1 & 4 \\
180+
3 & -1 & 4 \\
181+
4 & -1 & 5 \\
182+
5 & -1 & \boxed{5} \\
183+
\end{bmatrix}
184+
{{< /katex >}}
185+
186+
#### 复杂度分析
187+
188+
- **时间复杂度:** {{< katex >}}\Omicron(N){{< /katex >}}
189+
- **空间复杂度:** {{< katex >}}\Omicron(N){{< /katex >}}
190+
191+
{{< tabs "lc121-03" >}}
192+
{{< tab "Go" >}}
193+
194+
```go
195+
func maxProfit_3(prices []int) int {
196+
dp, n := make([][2]int, len(prices)), len(prices)
197+
dp[0][0], dp[0][1] = -prices[0], 0
198+
for i := 1; i < n; i++ {
199+
dp[i][0] = max(dp[i-1][0], -prices[i])
200+
dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
201+
}
202+
return dp[n-1][1]
203+
}
204+
```
205+
206+
{{< /tab >}}
207+
{{< /tabs >}}
208+
209+
## 总结
210+
211+
...
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
---
2+
weight: 33
3+
bookFlatSection: true
4+
title: "122.买卖股票的最佳时机 II"
5+
description: "122.买卖股票的最佳时机 II"
6+
---
7+
8+
# 122.买卖股票的最佳时机 II
9+
10+
## 题目描述
11+
12+
{{< button href="https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/" >}}题目地址{{< /button >}}
13+
{{< button href="https://github.com/kylesliu/awesome-golang-algorithm/tree/master/leetcode/101-200/0122.Best-Time-To-Buy-And-Sell-Stock-II" >}}代码{{< /button >}}
14+
15+
给定一个数组 prices ,其中`prices[i]`是一支给定股票第 i 天的价格。
16+
17+
设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
18+
19+
{{< hint info >}}
20+
**提示**
21+
22+
可以买卖多次
23+
{{< /hint >}}
24+
25+
### **示例 1**
26+
27+
```text
28+
输入: prices = [7,1,5,3,6,4]
29+
输出: 7
30+
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
31+
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3
32+
```
33+
34+
### **示例 2**
35+
36+
```text
37+
38+
输入: prices = [1,2,3,4,5]
39+
输出: 4
40+
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
41+
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
42+
```
43+
44+
### **限制**
45+
46+
- 1 <= prices.length <= 3 * 104
47+
- 0 <= prices[i] <= 104
48+
49+
## 题解
50+
51+
### 思路 1:**暴力循环**
52+
53+
**算法流程:**
54+
55+
2 次循环分别找出最大价格和最小价格
56+
57+
**复杂度分析:**
58+
59+
- **时间复杂度** `O(N^2))`
60+
- **空间复杂度** `O(1)`
61+
62+
#### 代码
63+
64+
{{< tabs "lc122-01" >}}
65+
{{< tab "Go" >}}
66+
67+
```go
68+
package main
69+
func maxProfit_1(prices []int) int {
70+
ans := 0
71+
for i := 1; i < len(prices); i++ {
72+
if prices[i] > prices[i-1] {
73+
ans += prices[i] - prices[i-1]
74+
}
75+
}
76+
return ans
77+
}
78+
```
79+
80+
{{< /tab >}}
81+
82+
{{< /tabs >}}
83+
84+
85+
### 思路 2:**动态规划**
86+
87+
#### 算法流程
88+
89+
基本动态规划操作...
90+
91+
#### 复杂度分析
92+
93+
- **时间复杂度** `O(N)`
94+
- **空间复杂度** `O(N)`
95+
96+
{{< tabs "lc733-02" >}}
97+
{{< tab "Go" >}}
98+
99+
```go
100+
func maxProfit_2(prices []int) int {
101+
dp, n := make([][2]int, len(prices)), len(prices)
102+
dp[0][0], dp[0][1] = -prices[0], 0
103+
for i := 1; i < n; i++ {
104+
dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
105+
dp[i][1] = max(dp[i-1][1], dp[i-1][0]+prices[i])
106+
}
107+
return dp[n-1][1]
108+
}
109+
```
110+
111+
{{< /tab >}}
112+
113+
{{< /tabs >}}
114+
115+
## 总结
116+
117+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 算法 题解:[awesome-golang-algorithm](https://github.com/kylesliu/awesome-golang-algorithm)

0 commit comments

Comments
 (0)