@@ -170,41 +170,54 @@ public:
170
170
Java:
171
171
172
172
``` java
173
- class Solution { // 动态规划
173
+ // 版本一: 三维 dp数组
174
+ class Solution {
174
175
public int maxProfit (int k , int [] prices ) {
175
- if (prices == null || prices. length < 2 || k == 0 ) {
176
- return 0 ;
177
- }
178
-
179
- // [天数][交易次数][是否持有股票]
180
- int [][][] dp = new int [prices. length][k + 1 ][2 ];
181
-
182
- // bad case
183
- dp[0 ][0 ][0 ] = 0 ;
184
- dp[0 ][0 ][1 ] = Integer . MIN_VALUE ;
185
- dp[0 ][1 ][0 ] = 0 ;
186
- dp[0 ][1 ][1 ] = - prices[0 ];
187
- // dp[0][j][0] 都均为0
188
- // dp[0][j][1] 异常值都取Integer.MIN_VALUE;
189
- for (int i = 2 ; i < k + 1 ; i++ ) {
190
- dp[0 ][i][0 ] = 0 ;
191
- dp[0 ][i][1 ] = Integer . MIN_VALUE ;
176
+ if (prices. length == 0 ) return 0 ;
177
+
178
+ // [天数][交易次数][是否持有股票]
179
+ int len = prices. length;
180
+ int [][][] dp = new int [len][k + 1 ][2 ];
181
+
182
+ // dp数组初始化
183
+ // 初始化所有的交易次数是为确保 最后结果是最多 k 次买卖的最大利润
184
+ for (int i = 0 ; i <= k; i++ ) {
185
+ dp[0 ][i][1 ] = - prices[0 ];
192
186
}
193
187
194
- for (int i = 1 ; i < prices . length ; i++ ) {
195
- for (int j = k ; j >= 1 ; j-- ) {
196
- // dp公式
188
+ for (int i = 1 ; i < len ; i++ ) {
189
+ for (int j = 1 ; j <= k ; j++ ) {
190
+ // dp方程, 0表示不持有/卖出, 1表示持有/买入
197
191
dp[i][j][0 ] = Math . max(dp[i - 1 ][j][0 ], dp[i - 1 ][j][1 ] + prices[i]);
198
192
dp[i][j][1 ] = Math . max(dp[i - 1 ][j][1 ], dp[i - 1 ][j - 1 ][0 ] - prices[i]);
199
193
}
200
194
}
195
+ return dp[len - 1 ][k][0 ];
196
+ }
197
+ }
201
198
202
- int res = 0 ;
203
- for (int i = 1 ; i < k + 1 ; i++ ) {
204
- res = Math . max(res, dp[prices. length - 1 ][i][0 ]);
199
+ // 版本二: 空间优化
200
+ class Solution {
201
+ public int maxProfit (int k , int [] prices ) {
202
+ if (prices. length == 0 ) return 0 ;
203
+
204
+ // [天数][股票状态]
205
+ // 股票状态: 奇数表示第 k 次交易持有/买入, 偶数表示第 k 次交易不持有/卖出, 0 表示没有操作
206
+ int len = prices. length;
207
+ int [][] dp = new int [len][k* 2 + 1 ];
208
+
209
+ // dp数组的初始化, 与版本一同理
210
+ for (int i = 1 ; i < k* 2 ; i += 2 ) {
211
+ dp[0 ][i] = - prices[0 ];
205
212
}
206
213
207
- return res;
214
+ for (int i = 1 ; i < len; i++ ) {
215
+ for (int j = 0 ; j < k* 2 - 1 ; j += 2 ) {
216
+ dp[i][j + 1 ] = Math . max(dp[i - 1 ][j + 1 ], dp[i - 1 ][j] - prices[i]);
217
+ dp[i][j + 2 ] = Math . max(dp[i - 1 ][j + 2 ], dp[i - 1 ][j + 1 ] + prices[i]);
218
+ }
219
+ }
220
+ return dp[len - 1 ][k* 2 ];
208
221
}
209
222
}
210
223
```
0 commit comments