@@ -170,41 +170,54 @@ public:
170170Java:
171171
172172``` java
173- class Solution { // 动态规划
173+ // 版本一: 三维 dp数组
174+ class Solution {
174175 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 ];
192186 }
193187
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表示持有/买入
197191 dp[i][j][0 ] = Math . max(dp[i - 1 ][j][0 ], dp[i - 1 ][j][1 ] + prices[i]);
198192 dp[i][j][1 ] = Math . max(dp[i - 1 ][j][1 ], dp[i - 1 ][j - 1 ][0 ] - prices[i]);
199193 }
200194 }
195+ return dp[len - 1 ][k][0 ];
196+ }
197+ }
201198
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 ];
205212 }
206213
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 ];
208221 }
209222}
210223```
0 commit comments