LeetCode:309. Best Time to Buy and Sell Stock with Cooldown

本文探讨了一种股票交易策略,通过动态规划算法计算在特定交易规则下(如冷却期)的最大可能利润。文章详细介绍了状态定义、状态转移方程,并展示了如何优化原始代码,将时间复杂度从O(n^2)降低到O(n)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

买卖股票系列的第5题。题目是:

Say you have an array for which the ith element is the price of a
given stock on day i.

Design an algorithm to find the maximum profit. You may complete as
many transactions as you like (ie, buy one and sell one share of the
stock multiple times) with the following restrictions:

You may not engage in multiple transactions at the same time (ie, you
must sell the stock before you buy again). After you sell your stock,
you cannot buy stock on next day. (ie, cooldown 1 day)

这里的特殊要求是卖出一次,需要等一天,才能重新买入。
题目不难,只是优化方面需要注意一下。

这题应该用动态规划来做。
状态定义:dp[i]:第i天能获得的最大利润
状态转移方程:dp[i] = max(dp[i-1], dp[j-2] + (prices[i] - prices[j])), 0 <= j < i,这里分别对应在第i天不卖和卖的情况。
很快写出代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty() || prices.size() == 1)
            return 0;
        int sz = prices.size();
        vector<int> dp(sz, 0);
        dp[1] = prices[1] > prices[0] ? prices[1] - prices[0] : 0;
        for (int i = 2; i < sz; ++i) {
            dp[i] = dp[i-1];
            for (int j = 0; j < i; ++j) {
                int temp = j-2 < 0 ? prices[i] - prices[j] : dp[j-2] + prices[i] - prices[j];
                if (temp > dp[i])
                    dp[i] = temp;
            }
        }
        return dp.back();
    }
};

代码写成这样会有效率低的问题。
我们观察状态转移方程,将后半部分化为:(dp[j-2] - prices[j]) + prices[i],
对于不同的i,(dp[j-2] - prices[j])的前面部分部分是一样的,也就是上面的代码重复计算了这一部分。进行优化后的代码是:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if (prices.empty() || prices.size() == 1)
            return 0;
        int sz = prices.size();
        vector<int> dp(sz, 0);
        dp[1] = prices[1] > prices[0] ? prices[1] - prices[0] : 0;
        int tempMax = max(-prices[0], -prices[1]);//tempMax = dp[j-2] - prices[j]
        for (int i = 2; i < sz; ++i) {
            tempMax = max(tempMax, dp[i-2] - prices[i]);
            dp[i] = max(dp[i-1], tempMax + prices[i]);
        }
        return dp.back();
    }
};

时间复杂度由原来的O(n^2)降低到O(n),优化的结果还行

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值