Merge pull request #915 from spacker-343/master

我这次可是有备而来,一网打尽股票问题
This commit is contained in:
程序员Carl
2021-11-26 09:11:13 +08:00
committed by GitHub
8 changed files with 102 additions and 76 deletions

View File

@ -194,7 +194,7 @@ public:
## 其他语言版本 ## 其他语言版本
Java Java:
> 贪心法: > 贪心法:
@ -242,11 +242,12 @@ class Solution {
class Solution { class Solution {
public int maxProfit(int[] prices) { public int maxProfit(int[] prices) {
int[] dp = new int[2]; int[] dp = new int[2];
// 记录一次交易,一次交易有买入卖出两种状态
// 0代表持有1代表卖出
dp[0] = -prices[0]; dp[0] = -prices[0];
dp[1] = 0; dp[1] = 0;
// 可以参考斐波那契问题的优化方式 // 可以参考斐波那契问题的优化方式
// dp[0] 和 dp[1], 其实是第 0 天的数据 // 我们从 i=1 开始遍历数组,一共有 prices.length 天,
// 所以我们从 i=1 开始遍历数组,一共有 prices.length 天,
// 所以是 i<=prices.length // 所以是 i<=prices.length
for (int i = 1; i <= prices.length; i++) { for (int i = 1; i <= prices.length; i++) {
// 前一天持有;或当天买入 // 前一天持有;或当天买入
@ -263,7 +264,7 @@ class Solution {
} }
``` ```
Python Python:
> 贪心法: > 贪心法:
```python ```python
@ -307,7 +308,8 @@ class Solution:
return dp[(length-1) % 2][1] return dp[(length-1) % 2][1]
``` ```
Go Go:
```Go ```Go
func maxProfit(prices []int) int { func maxProfit(prices []int) int {
length:=len(prices) length:=len(prices)
@ -334,7 +336,7 @@ func max(a,b int)int {
} }
``` ```
JavaScript JavaScript:
> 动态规划 > 动态规划

View File

@ -131,7 +131,7 @@ public:
## 其他语言版本 ## 其他语言版本
### Java Java:
```java ```java
// 贪心思路 // 贪心思路
@ -167,28 +167,8 @@ class Solution { // 动态规划
} }
``` ```
```java Python:
// 优化空间
class Solution {
public int maxProfit(int[] prices) {
int[] dp=new int[2];
// 0表示持有1表示卖出
dp[0]=-prices[0];
dp[1]=0;
for(int i=1; i<=prices.length; i++){
// 前一天持有; 或当天卖出然后买入
dp[0]=Math.max(dp[0], dp[1]-prices[i-1]);
// 前一天卖出; 或当天卖出,当天卖出,得先持有
dp[1]=Math.max(dp[1], dp[0]+prices[i-1]);
}
return dp[1];
}
}
```
### Python
```python ```python
class Solution: class Solution:
def maxProfit(self, prices: List[int]) -> int: def maxProfit(self, prices: List[int]) -> int:
@ -212,7 +192,8 @@ class Solution:
return dp[-1][1] return dp[-1][1]
``` ```
### Go Go:
```golang ```golang
//贪心算法 //贪心算法
func maxProfit(prices []int) int { func maxProfit(prices []int) int {
@ -248,7 +229,8 @@ func maxProfit(prices []int) int {
} }
``` ```
### Javascript Javascript:
贪心 贪心
```Javascript ```Javascript
var maxProfit = function(prices) { var maxProfit = function(prices) {
@ -284,7 +266,8 @@ const maxProfit = (prices) => {
}; };
``` ```
### C C:
```c ```c
int maxProfit(int* prices, int pricesSize){ int maxProfit(int* prices, int pricesSize){
int result = 0; int result = 0;

View File

@ -147,25 +147,30 @@ class Solution
} }
return dp[n - 1][0]; // 卖出股票收益高于持有股票收益,因此取[0] return dp[n - 1][0]; // 卖出股票收益高于持有股票收益,因此取[0]
} }
}
```
// 实现2变量存储 ```java
// 第一种方法需要用二维数组存储,有空间开销,其实关心的仅仅是前一天的状态,不关注更多的历史信息 // 优化空间
// 因此,可以仅保存前一天的信息存入 dp0、dp1 这 2 个变量即可 class Solution {
// 时间复杂度O(n)空间复杂度O(1)
public int maxProfit(int[] prices) { public int maxProfit(int[] prices) {
int n = prices.length; int[] dp = new int[2];
int dp0 = 0, dp1 = -prices[0]; // 定义变量,存储初始状态 // 0表示持有1表示卖出
for (int i = 1; i < n; ++i) { dp[0] = -prices[0];
int newDp0 = Math.max(dp0, dp1 + prices[i]); // 第 i 天,没有股票 dp[1] = 0;
int newDp1 = Math.max(dp1, dp0 - prices[i]); // 第 i 天,持有股票 for(int i = 1; i <= prices.length; i++){
dp0 = newDp0; // 前一天持有; 既然不限制交易次数,那么再次买股票时,要加上之前的收益
dp1 = newDp1; dp[0] = Math.max(dp[0], dp[1] - prices[i-1]);
// 前一天卖出; 或当天卖出,当天卖出,得先持有
dp[1] = Math.max(dp[1], dp[0] + prices[i-1]);
} }
return dp0; return dp[1];
} }
} }
``` ```
Python Python
> 版本一: > 版本一:

View File

@ -188,7 +188,7 @@ dp[1] = max(dp[1], dp[0] - prices[i]); 如果dp[1]取dp[1],即保持买入股
## 其他语言版本 ## 其他语言版本
### Java Java:
```java ```java
// 版本一 // 版本一
@ -221,30 +221,30 @@ class Solution {
// 版本二: 空间优化 // 版本二: 空间优化
class Solution { class Solution {
public int maxProfit(int[] prices) { public int maxProfit(int[] prices) {
int[] dp=new int[4]; int[] dp = new int[4];
// 存储两的状态就行了 // 存储两次交易的状态就行了
// dp[0]代表第一次买入 // dp[0]代表第一次交易的买入
dp[0]=-prices[0]; dp[0] = -prices[0];
// dp[1]代表第一次卖出 // dp[1]代表第一次交易的卖出
dp[1]=0; dp[1] = 0;
// dp[2]代表第二次买入 // dp[2]代表第二次交易的买入
dp[2]=-prices[0]; dp[2] = -prices[0];
// dp[3]代表第二次卖出 // dp[3]代表第二次交易的卖出
dp[3]=0; dp[3] = 0;
for(int i=1; i<=prices.length; i++){ for(int i = 1; i <= prices.length; i++){
// 要么保持不变,要么没有就买,有了就卖 // 要么保持不变,要么没有就买,有了就卖
dp[0]=Math.max(dp[0], -prices[i-1]); dp[0] = Math.max(dp[0], -prices[i-1]);
dp[1]=Math.max(dp[1], dp[0]+prices[i-1]); dp[1] = Math.max(dp[1], dp[0]+prices[i-1]);
// 这已经是第二了,所以得加上前一卖出去的价格 // 这已经是第二次交易了,所以得加上前一次交易卖出去的收获
dp[2]=Math.max(dp[2], dp[1]-prices[i-1]); dp[2] = Math.max(dp[2], dp[1]-prices[i-1]);
dp[3]=Math.max(dp[3], dp[2]+prices[i-1]); dp[3] = Math.max(dp[3], dp[2]+ prices[i-1]);
} }
return dp[3]; return dp[3];
} }
} }
``` ```
### Python Python:
> 版本一: > 版本一:
```python ```python
@ -311,9 +311,7 @@ func max(a,b int)int{
} }
``` ```
JavaScript:
### JavaScript
> 版本一: > 版本一:
@ -352,7 +350,7 @@ const maxProfit = prices => {
}; };
``` ```
### Go Go:
> 版本一: > 版本一:
```go ```go

View File

@ -165,7 +165,7 @@ public:
## 其他语言版本 ## 其他语言版本
Java Java:
```java ```java
// 版本一: 三维 dp数组 // 版本一: 三维 dp数组
@ -228,9 +228,9 @@ class Solution {
if(k == 0){ if(k == 0){
return 0; return 0;
} }
// 其实就是123题的扩展123题只用记录2的状态 // 其实就是123题的扩展123题只用记录2次交易的状态
// 这里记录k的状态就行了 // 这里记录k次交易的状态就行了
// 每都有买入,卖出两个状态,所以要乘 2 // 每次交易都有买入,卖出两个状态,所以要乘 2
int[] dp = new int[2 * k]; int[] dp = new int[2 * k];
// 按123题解题格式那样做一个初始化 // 按123题解题格式那样做一个初始化
for(int i = 0; i < dp.length / 2; i++){ for(int i = 0; i < dp.length / 2; i++){
@ -246,15 +246,16 @@ class Solution {
dp[j + 1] = Math.max(dp[j + 1], dp[j] + prices[i - 1]); dp[j + 1] = Math.max(dp[j + 1], dp[j] + prices[i - 1]);
} }
} }
// 返回最后一卖出状态的结果就行了 // 返回最后一次交易卖出状态的结果就行了
return dp[dp.length - 1]; return dp[dp.length - 1];
} }
} }
``` ```
Python:
Python
版本一 版本一
```python ```python
class Solution: class Solution:
def maxProfit(self, k: int, prices: List[int]) -> int: def maxProfit(self, k: int, prices: List[int]) -> int:
@ -285,8 +286,10 @@ class Solution:
dp[j] = max(dp[j],dp[j-1]+prices[i]) dp[j] = max(dp[j],dp[j-1]+prices[i])
return dp[2*k] return dp[2*k]
``` ```
Go Go:
版本一: 版本一:
```go ```go
// 买卖股票的最佳时机IV 动态规划 // 买卖股票的最佳时机IV 动态规划
// 时间复杂度O(kn) 空间复杂度O(kn) // 时间复杂度O(kn) 空间复杂度O(kn)
@ -356,10 +359,7 @@ func max(a,b int)int{
} }
``` ```
Javascript:
Javascript
```javascript ```javascript
// 方法一:动态规划 // 方法一:动态规划

View File

@ -185,6 +185,28 @@ class Solution {
} }
``` ```
```java
// 一维数组优化
class Solution {
public int maxProfit(int[] prices) {
int[] dp=new int[4];
dp[0] = -prices[0];
dp[1] = 0;
for(int i = 1; i <= prices.length; i++){
// 使用临时变量来保存dp[0], dp[2]
// 因为马上dp[0]和dp[2]的数据都会变
int temp = dp[0];
int temp1 = dp[2];
dp[0] = Math.max(dp[0], Math.max(dp[3], dp[1]) - prices[i-1]);
dp[1] = Math.max(dp[1], dp[3]);
dp[2] = temp + prices[i-1];
dp[3] = temp1;
}
return Math.max(dp[3],Math.max(dp[1],dp[2]));
}
}
```
Python Python

View File

@ -196,7 +196,9 @@ class Solution { // 动态规划
``` ```
Python Python
```python ```python
class Solution: # 贪心思路 class Solution: # 贪心思路
def maxProfit(self, prices: List[int], fee: int) -> int: def maxProfit(self, prices: List[int], fee: int) -> int:

View File

@ -134,6 +134,20 @@ public int maxProfit(int[] prices, int fee) {
} }
return Math.max(dp[len - 1][0], dp[len - 1][1]); return Math.max(dp[len - 1][0], dp[len - 1][1]);
} }
// 一维数组优化
class Solution {
public int maxProfit(int[] prices, int fee) {
int[] dp = new int[2];
dp[0] = -prices[0];
dp[1] = 0;
for (int i = 1; i <= prices.length; i++) {
dp[0] = Math.max(dp[0], dp[1] - prices[i - 1]);
dp[1] = Math.max(dp[1], dp[0] + prices[i - 1] - fee);
}
return dp[1];
}
}
``` ```
Python Python