力扣第188题 买卖股票的最佳时机 IV c++ 动态规划题 附Java代码
题目
困难
相关标签
给你一个整数数组 prices
和一个整数 k
,其中 prices[i]
是某支给定的股票在第 i
天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 k
笔交易。也就是说,你最多可以买 k
次,卖 k
次。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:k = 2, prices = [2,4,1] 输出:2 解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。
示例 2:
输入:k = 2, prices = [3,2,6,5,0,3] 输出:7 解释:在第 2 天 (股票价格 = 2) 的时候买入,在第 3 天 (股票价格 = 6) 的时候卖出, 这笔交易所能获得利润 = 6-2 = 4 。 随后,在第 5 天 (股票价格 = 0) 的时候买入,在第 6 天 (股票价格 = 3) 的时候卖出, 这笔交易所能获得利润 = 3-0 = 3 。
提示:
1 <= k <= 100
1 <= prices.length <= 1000
0 <= prices[i] <= 1000
思路和解题方法
- 首先创建了一个二维数组
dp
,用来存储每个状态下的最大收益。数组的行数为prices
数组的大小,列数为2*k+1
,因为每次交易包括买入和卖出两个操作。- 接着,通过两层循环遍历
prices
数组和dp
数组,计算每个状态下的最大收益。其中,第一层循环是遍历prices
数组,第二层循环是遍历每次交易的买入和卖出操作。- 在每次交易的买入操作中,使用状态转移方程
dp[i][j+1] = max(dp[i-1][j+1], dp[i-1][j] - prices[i])
,表示当前状态下选择买入或保持不变的最大收益。- 在每次交易的卖出操作中,使用状态转移方程
dp[i][j+2] = max(dp[i-1][j+2], dp[i-1][j+1] + prices[i])
,表示当前状态下选择卖出或保持不变的最大收益。- 最后,返回
dp[prices.size() - 1][2*k]
,即最后一天,进行了2k次交易后的最大收益。
复杂度
时间复杂度:
O(n*k)
时间复杂度为O(n*k),其中n是prices数组的大小,k是最多可以进行的交易次数。
在第一个循环中,遍历了2k个元素,而在第二个循环中,遍历了n个元素,所以总的时间复杂度为O(nk)。
空间复杂度
O(n*k)
空间复杂度方面,使用了一个二维数组dp来存储每个状态下的最大收益,其大小为prices.size() * (2k+1)。因此,空间复杂度也是O(nk),随着输入规模的增加,空间消耗会相应增加。
c++ 代码
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
// 创建一个二维数组 dp,用来记录每天的最大收益
vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));
// 初始化第一天的买入状态
for (int j = 1; j <= 2 * k; j += 2) {
dp[0][j] = -prices[0];
}
// 遍历每一天的状态
for (int i = 1; i < prices.size(); i++) {
// 遍历偶数列,即卖出状态
for (int j = 0; j < 2 * k - 1; j += 2) {
// 更新买入状态和卖出状态的最大收益
dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
}
}
return dp[prices.size() - 1][2 * k];
}
};
附Java代码
class Solution {
public int maxProfit(int k, int[] prices) {
if (prices.length == 0) return 0;
// [天数][股票状态]
// 股票状态: 奇数表示第 k 次交易持有/买入, 偶数表示第 k 次交易不持有/卖出, 0 表示没有操作
int len = prices.length;
int[][] dp = new int[len][k*2 + 1];
// dp数组的初始化, 与版本一同理
for (int i = 1; i < k*2; i += 2) {
dp[0][i] = -prices[0];
}
for (int i = 1; i < len; i++) {
for (int j = 0; j < k*2 - 1; j += 2) {
dp[i][j + 1] = Math.max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);
dp[i][j + 2] = Math.max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
}
}
return dp[len - 1][k*2];
}
}
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)