剑指 Offer 63. 股票的最大利润

本文介绍了一种通过动态规划求解股票买卖最大利润的方法。利用数组记录每天的最低买入价格和截止当天的最大利润,实现高效计算。适用于股票交易策略制定。

假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 =6)的时候卖出,最大利润 = 6-1 = 5 。注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例 2:

输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

方法:动态规划

状态定义: dp[i]dp[i]dp[i]为截止到第i天所获得的最大利润

状态转移:

  • minnminnminn存放截止到第iii天时,最小的股票价格。

在这里插入图片描述

此时会有三种情况:

  1. iii天的价格小于等于前i−1i-1i1天的最小价格,此时前iii天的最小价格为prices[i]prices[i]prices[i],此时最大利润会变吗,现在是最低价肯定不能卖啊,所以利润还是之前的利润,dp[i]=dp[i−1]dp[i] = dp[i-1]dp[i]=dp[i1]
  2. iii天的价格大于前i−1i-1i1天的最小价格,这时候就要比较一下如果今天卖出的利润了,如果prices[i]−minn>dp[i−1]prices[i]-minn > dp[i-1]prices[i]minn>dp[i1],那证明今天卖的利润是有史以来最大,必须果断卖,就有dp[i]=prices[i]−minndp[i] = prices[i]-minndp[i]=prices[i]minn
  3. iii天的价格仍大于前i−1i-1i1天的最小价格,但此时prices[i]−minn<=dp[i−1]prices[i]-minn <= dp[i-1]prices[i]minn<=dp[i1],证明今天卖的话没有以前合适,那利润仍不变,dp[i]=dp[i−1]dp[i] = dp[i-1]dp[i]=dp[i1]

以上就是状态转移的三种情况

初始状态: dp[0]=0,dp[1]=max(prices[1]−prices[0],0)dp[0] = 0,dp[1] = max(prices[1]-prices[0], 0)dp[0]=0dp[1]=max(prices[1]prices[0],0);初始状态时minn=min(prices[0],prices[1])minn = min(prices[0],prices[1])minn=min(prices[0],prices[1])
返回值: dp[]dp[]dp[]中最后一项

python

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        l = len(prices)
        if l == 0 or l == 1: return 0
        dp = [0]*l
        minn = min(prices[0],prices[1])
        dp[1] = max(prices[1]-prices[0],0)
        for i in range(2,l):
            if prices[i]<=minn: # 此时只是把最小值换了,此时还不能卖呢,利润仍不变
                dp[i] = dp[i-1]
                minn = prices[i]
            elif (prices[i]-minn)> dp[i-1]: 
                dp[i] = (prices[i]-minn)
            else:
                dp[i] = dp[i-1]
        return dp[-1]

C++

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int l = prices.size();
        if(l == 0 ||l == 1) return 0;
        int dp[l];
        int minn = min(prices[0], prices[1]);
        dp[1] = max(prices[1]-prices[0], 0);
        for(int i=2; i<l; i++){
            if (prices[i]<=minn){
                dp[i] = dp[i-1];
                minn = prices[i];
            }
            else if((prices[i]-minn)> dp[i-1]) dp[i] = prices[i]-minn;
            else dp[i] = dp[i-1];
        }
    return dp[l-1];
    }
};
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值