当前位置: 首页 > article >正文

Leetcode 188. 买卖股票的最佳时机 Ⅳ 状态机dp C++实现

Leetcode 188.买卖股票的最佳时机 Ⅳ

问题:给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

算法:递归搜索 + 保存计算结果 = 记忆化搜索

        在 Leetcode122. 买卖股票 状态机dp C++实现 的基础上,添加一个参数 j,表示当前可以至多交易 j 次。

注意:由于最后未持有股票,手上的股票一定会卖掉,所以代码中的 j-1 可以是在买股票的时候,也可以是在卖股票的时候,这两种写法都是可以的。

以下代码参数 j 的修改时机为买入时。

时间复杂度:O(nk),其中 n 为 prices 的长度。

空间复杂度:O(nk)

代码:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        vector<vector<array<int, 2>>> memo(n, vector<array<int, 2>>(k + 1, {-1, -1})); // -1 表示还没有计算过
        auto dfs = [&](auto&& dfs, int i, int j, bool hold) -> int {
            if (j < 0)  return INT_MIN / 2; // 除 2 防止溢出
            if (i < 0)  return hold ? INT_MIN / 2 : 0;

            int& res = memo[i][j][hold]; // 注意这里是引用
            if (res != -1)  return res;// 之前计算过
            if (hold)   return res = max(dfs(dfs, i - 1, j, true), dfs(dfs, i - 1, j - 1, false) - prices[i]);
            return res = max(dfs(dfs, i - 1, j, false), dfs(dfs, i - 1, j, true) + prices[i]);
        };
        return dfs(dfs, n - 1, k, false);
    }
};

算法:1:1 翻译成递推

时间复杂度:O(nk),其中 n 为 prices 的长度。

空间复杂度:O(nk)

代码:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        int n = prices.size();
        vector<vector<array<int, 2>>> dp(n + 1, vector<array<int, 2>>(k + 2, {INT_MIN / 2, INT_MIN / 2}));
        for(int j = 1;j <= k + 1;j++)   dp[0][j][0] = 0;
        for(int i = 0;i < n;i++)
            for(int j = 1;j <= k + 1;j++){
                dp[i + 1][j][0] = max(dp[i][j][0],dp[i][j][1] + prices[i]);
                dp[i + 1][j][1] = max(dp[i][j][1],dp[i][j - 1][0] - prices[i]);
            }
            return dp[n][k + 1][0];
    }
};

算法:空间优化

必须倒序遍历。

时间复杂度:O(nk),其中 n 为 prices 的长度。

空间复杂度:O(k)

代码:

class Solution {
public:
    int maxProfit(int k, vector<int>& prices) {
        vector<array<int, 2>> dp(k + 2, {INT_MIN / 2, INT_MIN / 2});
        for(int j = 1;j <= k + 1;j++)   dp[j][0] = 0;
        for(int p : prices)
            for(int j = k + 1;j > 0;j--){
                dp[j][0] = max(dp[j][0],dp[j][1] + p);
                dp[j][1] = max(dp[j][1],dp[j - 1][0] - p);
            }
            return dp[k + 1][0];
    }
};

http://www.kler.cn/a/301171.html

相关文章:

  • WebRTC 和 WebSocket
  • 【第七节】在RadAsm中使用OllyDBG调试器
  • 《通往人工智能深度学习专家之路:全面解析学习路线图》
  • Gin HTML 模板渲染
  • 鸿蒙网络编程系列48-仓颉版UDP回声服务器示例
  • 深度学习:卷积神经网络的计算复杂度,顺序操作,最大路径长度
  • MAC配置chromedriver
  • EasyExcel 学习之 导出 “类型及精度问题”
  • Tomact的基本使用
  • 中国大数据产业的融资热潮来袭,哪些领域最受资本青睐?
  • 设计模式】Listener模式和Visitor模式的区别
  • 在JavaScript中实现简单的发布/订阅模式
  • 《C++位域:在复杂数据结构中的精准驾驭与风险规避》
  • spark读取csv文件
  • 云计算第四阶段----CLOUD 01-03
  • MySQL:视图【详解】
  • socket通讯原理及例程(详解)
  • Spring Framework系统框架
  • 函数栈帧的小知识理解
  • GEE :利用MODIS土地分类数据监测指定区域2001-2024年农作物的时序面积
  • 用HTML写一个动态的的电子相册实战详细案例
  • 论文阅读翻译之Deep reinforcement learning from human preferences
  • 分布式风电电池储能系统
  • ucx 编译安装检验方式备忘
  • 大模型笔记02--基于fastgpt和oneapi构建大模型应用平台
  • Axure高效打造大屏可视化BI数据展示