算法详解4:买卖股票的最佳时机系列(上)

文章目录

算法详解4:买卖股票的最佳时机系列(上)

121.买卖股票的最佳时机

先阅读题目要求:

题目要求我们在某一天进行买入然后在之后的日子里面卖出从而获取最大利益。

那么我们只要获取一个最小值和一个最大值,然后让其相减即可得到最大利益。

那么上述操作可行吗?

我们将示例1代入到我们的方法中去获取了最小值1,但是最大值是7。因为不能使用7 - 1所以这种方法不可以。

那么还能怎么处理呢?

我们不获取卖出时候的价格,只获取卖出时候的利润即可。此时我们只需要处理最小值即可。

test 复制代码
伪代码:
answer = max(answer, 此时卖出的利润);

细节处理:

因为可能在卖出时出现负数,所以answer初始化为0。

要求最小值所以可以给INT_MAX0x3f3f3f3f

cpp 复制代码
int maxProfit(vector<int>& prices) {
        int answer = 0;
        int minProfit = INT_MAX;

        for (int i = 0; i < prices.size(); ++i) {
            minProfit = std::min(minProfit, prices[i]);
            answer = std::max(answer, prices[i] - minProfit);
        }

        return answer;
    }

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

先阅读题目要求:

题目要求我们在可以当天多次买卖股票,但是手中最多只能持有1股,然后获取最大利润。

和上一题不一样的是这道题可以当天多次买入和卖出。

那么该怎么处理呢?

由于题目要求我们手中只能持有1股,所以在每天结束的时候我们手中就会出现持有股票和没有股票两种状态。那么我们不需要纠结今天到底该不该交易,我们只需要关注今天结束时,这两种状态下我的'口袋里的现金'分别是多少。

因为利润可以理解为手中的现金余额。买入股票就是"花掉现金",所以利润减少;卖出股票就是"获得现金",利润增加。

使用变量:

cpp 复制代码
int dp0 = 0, dp1 = -prices[0];

int newDp0 = max(dp0,dp1 + prices[i]);
int newDp1 = max(dp1,dp0 - prices[i]);

dp0 = newDp0;
dp1 = newDp1;

使用数组:

cpp 复制代码
vector<vector<int>> dp(n,vector<int>(2));
dp[0][0] = 0;
dp[0][1] = -prices[0];

dp[i][0] = max(dp[i - 1][0],dp[i - 1][1] +  prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);

完整代码(使用数组版)

cpp 复制代码
int maxProfit(vector<int>& prices) {
        int n = prices.size();
        if (n == 0) return 0;

        // dp[i][0] 无股票, dp[i][1] 有股票
        vector<vector<int>> dp(n, vector<int>(2));
        
        // 初始化
        dp[0][0] = 0;
        dp[0][1] = -prices[0];

        for (int i = 1; i < n; i++) {
            dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]);
            dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]);
        }

        return dp[n-1][0];
    }

完整代码(使用变量版)

cpp 复制代码
 int maxProfit(vector<int>& prices) {
        // 因为只能持有一支股票,那就不能在最低价进行抄底,
        // 那么只能当天买入或者前一天买入然后当天卖出或者前一天卖出才能得到最高利润
        int n = prices.size();
        int dp0 = 0, dp1 = -prices[0];

        for (int i = 0; i < n; ++i) {
            // 每一天都计算一下最高利润然后给给dp0 和 dp1
            int newDp0 = std::max(dp0, dp1 + prices[i]);
            int newDp1 = std::max(dp1, dp0 - prices[i]);

            dp0 = newDp0;
            dp1 = newDp1;
        }

        return dp0;
    }
相关推荐
Gigavision4 小时前
基于BUAA-MIHR数据集的噪声解耦对比学习算法
人工智能·python·深度学习·算法
鹿角片ljp5 小时前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
彧azz6 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
Beyond_System|系统之外7 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
漂流瓶jz9 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
叠层归一研究院10 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia11 小时前
Diffusion Model 的基本原理与模型架构
算法
wabs66612 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin0312 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
shehuiyuelaiyuehao13 小时前
算法50,分治归并,数组中的逆序对
java·算法