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

文章目录

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

121.买卖股票的最佳时机

先阅读题目要求:

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

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

那么上述操作可行吗?

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

那么还能怎么处理呢?

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

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

细节处理:

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

要求最小值所以可以给INT_MAX或0x3f3f3f3f

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;
    }
相关推荐
行者全栈架构师5 分钟前
【鸿蒙心迹】鸿蒙网络请求架构实战——@ohos.net.http 到 Axios 封装、拦截器与统一错误处理(HarmonyOS 7.x)
前端·算法·架构
小宋102120 分钟前
OpenTelemetry GenAI可观测性实战:串起模型、工具、Token与错误
java·人工智能·算法·贪心算法
嫂子开门我是_我哥21 分钟前
青少年抑郁、焦虑、失眠与自杀相关表现的症状联系:一篇网络分析论文所使用的算法深度解读
论文阅读·算法·论文笔记
渊鱼L32 分钟前
CAD随机颗粒插件2D V2.0 更新说明
算法
Lazionr33 分钟前
unordered_map和unordered_set的使用
开发语言·c++·算法
行者全栈架构师39 分钟前
从 55% 到 6%:一个快餐营养规划器的算法迭代实录
后端·算法·架构
Laurie三省1 小时前
现场版却配上录音室版的歌词?聊聊我给开源 Mac 歌词软件写的多源打分算法
算法·macos·go
对空六课1 小时前
Vue 组件曝光埋点为什么会重复触发?去重方案与实现思路
服务器·前端·算法·数据分析
HZY1618yzh1 小时前
下一代编程语言出炉
c++·算法
CoderYanger1 小时前
A.每日一题:856. 括号的分数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法