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

Leetcode122. 买卖股票 状态机dp C++实现

Leetcode 122. 买卖股票的最佳时机

问题:给你一个整数数组 prices ,其中 prices [ i ] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回你能获得的最大利润 。


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

        每天可以有两种状态,持有股票或未持有股票,所对应的状态转移方程也不同,如下图。

        从后向前递归,递归边界是第 0 天时,第 0 天不可能持有股票,但是递归过程中,会出现第 0 天的状态是 hold(持有)的情况,所以我们把这种情况的返回值设置成 INT_MIN ,这样就不会影响最后的输出。

        递归入口是第 n 天时,由于第 n 天时未持有股票一定比持有股票利润大,所以递归入口状态设置成 false(未持有)。

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<array<int,2>> memo(n,{-1,-1});
        auto dfs = [&](auto &&dfs,int i,bool hold){
            if(i < 0)   return hold ? INT_MIN : 0; // INT_MIN 是因为第0天不可能持有股票,此时我们return一个最小值来保证其他递归的正确性
            int& res = memo[i][hold];
            if(res != -1)   return res;// 之前被计算过了
            if(hold)    return res = max(dfs(dfs,i-1,true),dfs(dfs,i-1,false) - prices[i]); // 当天持有
            return res = max(dfs(dfs,i-1,false),dfs(dfs,i-1,true) + prices[i]); // 当天未持有
        };
        return dfs(dfs,n-1,false); // 递归入口
    }
};

算法2:1:1 翻译成递推

        创建二维数组 dp ,并给 dp [ 0 ] [ 1 ] 赋初始值 INT_MIN ,遍历,列出状态转移方程。

代码:

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

算法3:空间优化

        算法1算法2 可知,我们在使用 dp 数组时只用到了相邻的两个格子,所以为了节省空间,我们可以不使用数组,仅使用变量来存储数据。dp0 表示未持有股票的利润,dp1 表示当前持有股票的利润。

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int dp0 = 0,dp1 = INT_MIN;
        for(int p : prices){
            int new_dp0 = max(dp0,dp1 + p);
            dp1 = max(dp1,dp0 - p);
            dp0 = new_dp0;
        }
        return dp0;
    }
};

算法4:

遍历数组,与标记到的最低价进行比较,画一个折线图,将所有的上升(红色)线段加起来即可得到答案。

代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size(),ans = 0;
        for(int i = n - 1;i > 0;i--)    prices[i] -= prices[i - 1];
        prices[0] = 0;
        for(int p : prices)
            if(p > 0)   ans += p;
        return ans;
    }
};


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

相关文章:

  • js 查找数组对象中id相同的元素,把他们放到新数组对象中
  • linux系统下PostgreSQL的使用
  • Spring Boot @AllArgsConstructor 还是 @RequiredArgsConstructor
  • 汇编语言知识基础介绍
  • 【网络原理】❤️Tcp 核心机制❤️ 通晓可靠传输的秘密, 保姆式教学, 建议收藏 !!!
  • 算法day09 二叉树
  • 损坏SD数据恢复的8种有效方法
  • 828华为云征文|采用Flexus云服务器X实例部署RTSP直播服务器
  • Playwright 测试:如何在云端使用 Browserless 运行?
  • 数据结构的简单认识
  • 速盾:直播 cdn 服务器带宽?
  • k8s--关于pod方面问题的排错思路与方法
  • 七、Maven继承和聚合关系、及Maven的仓库及查找顺序
  • uniapp 给画作生成画框
  • 又考了两个Oracle认证:RAC和DataGuard,文末送资料
  • VMware虚拟机上安装openfileresa开源的NAS存储管理解决方案和ISCSI共享磁盘存储
  • Springboot整合【Kafka】
  • 【4.1】图搜索算法-BFS和DFS解奇偶树
  • [数据集][目标检测]井盖丢失未盖破损检测数据集VOC+YOLO格式2890张5类别
  • 软件开发人员从0到1实现物联网项目:项目架构的思考