Best Time to Buy and Sell Stock IV
Description
Given an array prices and the i-th element of it represents the price of a stock on the i-th day.
You may complete at most k transactions. What's the maximum profit?
You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example
样例 1:
输入: k = 2, prices = [4, 4, 6, 1, 1, 4, 2 ,5]
输出: 6
解释: 以 4 买入, 以 6 卖出. 然后再以 1 买入, 以 5 卖出. 利润为 2 + 4 = 6.
样例 2:
输入: k = 1, prices = [3, 2, 1]
输出: 0
解释: 不进行交易
Challenge
O(nk) 时间复杂度. n 是 prices 数组的大小.
思路:
假设一共有 n 天, 那么这 n 天最多能够完成 n / 2 比交易, 也就是说, 当 k * 2 >= n 时, 就变成了 买卖股票的最佳时机 II, 反之, 我们可以作为动态规划问题解决:
定义:
- globalbest[i][j] 表示前i天,至多进行j次交易时的最大获益
- mustsell[i][j] 表示前i天,至多进行j次交易,并且第i天卖出手中的股票时的最大获益
状态转移:
mustsell[i][j] = max(globalbest[i - 1][j - 1], mustsell[i - 1][j]) + prices[i] - prices[i - 1]globalbest[i][j] = max(globalbest[i - 1][j], mustsell[i][j])
边界: mustsell[0][i] = globalbest[0][i] = 0
优化: 滚动数组优化两个状态的空间至一维数组.
public class Solution {
/**
* @param K: An integer
* @param prices: An integer array
* @return: Maximum profit
*/
public int maxProfit(int K, int[] P) {
int n = P.length;
if (n == 0) {
return 0;
}
int i, j, k;
if (K > n / 2) {
// best time to buy and sell stock ii
int tmp = 0;
for (i = 0; i < n - 1; ++i) {
tmp += Math.max(0, P[i + 1] - P[i]);
}
return tmp;
}
int[][] f = new int[n + 1][2 * K + 1 + 1];
for (k = 1; k <= 2 * K + 1; ++k) {
f[0][k] = Integer.MIN_VALUE; // impossible
}
f[0][1] = 0;
for (i = 1; i <= n; ++i) {
// 阶段1, 3, .. 2 * K + 1: f[i][j] = max{f[i-1][j], f[i-1][j-1] + Pi-1 – Pi-2}
for (j = 1; j <= 2 * K + 1; j += 2) {
f[i][j] = f[i - 1][j];
if (j > 1 && i > 1 && f[i - 1][j - 1] != Integer.MIN_VALUE) {
f[i][j] = Math.max(f[i][j], f[i - 1][j - 1] + P[i - 1] - P[i - 2]);
}
}
// 阶段2, 4.., 2K: f[i][j] = max{f[i-1][j] + Pi-1 – Pi-2, f[i-1][j-1]}
for (j = 2; j <= 2 * K + 1; j += 2) {
f[i][j] = f[i - 1][j - 1];
if (i > 1 && f[i - 1][j] != Integer.MIN_VALUE) {
f[i][j] = Math.max(f[i][j], f[i - 1][j] + P[i - 1] - P[i - 2]);
}
}
}
int res = 0;
for (j = 1; j <= 2 * K + 1; j += 2) {
res = Math.max(res, f[n][j]);
}
return res;
}
}

浙公网安备 33010602011771号