题目地址:
https://www.lintcode.com/problem/best-time-to-buy-and-sell-stock-iii/description
给定一个股票的价格,以长 n n n的数组 p p p的形式给出。规定每天只能做一次交易,并且每次只能买 1 1 1股,问如果只允许做最多 2 2 2次买卖,那么最大收益是多少。
前后缀分解的方法参考https://blog.csdn.net/qq_46105170/article/details/113668198。下面写的是用了状态机动态规划方法。
思路是状态机。参考https://blog.csdn.net/qq_46105170/article/details/109007301。代码如下:
import java.util.Arrays;
public class Solution {
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int[] prices) {
// write your code here
if (prices == null || prices.length == 0) {
return 0;
}
int len = prices.length;
int[][] buy = new int[len][3], sell = new int[len][3];
Arrays.fill(buy[0], -prices[0]);
buy[0][0] = Integer.MIN_VALUE;
for (int i = 1; i < len; i++) {
for (int j = 0; j <= 2; j++) {
buy[i][j] = buy[i - 1][j];
if (j > 0) {
buy[i][j] = Math.max(buy[i][j], sell[i - 1][j - 1] - prices[i]);
}
sell[i][j] = Math.max(sell[i - 1][j], buy[i - 1][j] + prices[i]);
}
}
return sell[len - 1][2];
}
}
时空复杂度 O ( n ) O(n) O(n)。
考虑空间优化。可以用滚动数组:
import java.util.Arrays;
public class Solution {
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int[] prices) {
// write your code here
if (prices == null || prices.length == 0) {
return 0;
}
int len = prices.length;
int[][] buy = new int[2][3], sell = new int[2][3];
Arrays.fill(buy[0], -prices[0]);
buy[0][0] = Integer.MIN_VALUE;
for (int i = 1; i < len; i++) {
for (int j = 0; j <= 2; j++) {
buy[i & 1][j] = buy[i - 1 & 1][j];
if (j > 0) {
buy[i & 1][j] = Math.max(buy[i & 1][j], sell[i - 1 & 1][j - 1] - prices[i]);
}
sell[i & 1][j] = Math.max(sell[i - 1 & 1][j], buy[i - 1 & 1][j] + prices[i]);
}
}
return sell[len - 1 & 1][2];
}
}
时间复杂度不变,空间 O ( 1 ) O(1) O(1)。