剑指 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。
 

限制:

0 <= 数组长度 <= 10^5

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:显然是一道动归题,我也难得自己完完全全写出来并且一遍过。主要找规律:

设dp[i]为在第i天卖掉股票所得到的最大利润,则

dp[i]和dp[i-1]之间有什么关系呢?

可以看到,假如dp[i-1]为5,说明在i-1天卖掉,最多能赚5,

如果prices[i]>prices[i-1],说明第i天卖能比第i-1天卖赚的更多,多多少呢,多的部分就是prices[i]-prices[i-1]

如果prices[i]<prices[i-1],说明第i天卖能比第i-1天卖亏损,亏多少呢,亏的部分就是prices[i]-prices[i-1]

并且如果prices[i]<prices[i-1],假定亏损=prices[i]-prices[i-1],如果亏损>dp[i-1],说明今天卖不仅不赚钱,还赔钱,那就不卖了,利润为0。如果亏损<dp[i-1],说明今天卖还是能赚点钱的,只不过赚的没有昨天多,赚的利润为dp[i-1]-(prices[i]-prices[i-1])

可以得出动态规划的方程:

            if(prices[i]>prices[i-1])
            dp[i]=dp[i-1]+prices[i]-prices[i-1];
            else
            {
               
                if(prices[i-1]-prices[i]>dp[i-1])
                dp[i]=0;
                else
                dp[i]=dp[i-1]-(prices[i-1]-prices[i]);
            }

具体代码如下:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        // 计算数组长度len
        int len=prices.size();
        // 长度为0或者1时,返回0
        if(len==0||len==1) return 0;
        // dp[i]代表第i天卖出股票所能得到的最大利润
        int dp[len];
        // dp[0]=0显而易见
        dp[0]=0;
        // 之后每一天都进行循环
        for(int i=1;i<len;i++)
        {
            // 如果当天的价格>昨天的价格 那么相比于昨天,今天卖能赚更多
            // 而且是在昨天卖出的基础上,多赚了两天之间的差值,即prices[i]-prices[i-1]
            if(prices[i]>prices[i-1])
            dp[i]=dp[i-1]+prices[i]-prices[i-1];
            // 如果当天的价格<昨天的价格 那么相比于昨天,今天卖会亏损一些
            else
            {
                // 昨天卖,赚的利润是dp[i-1],今天卖会有亏损,亏损是prices[i-1]-prices[i]
                // 如果亏损比昨天赚的利润还要大,即今天卖掉还要赔钱,那不如不卖,利润记为0
                if(prices[i-1]-prices[i]>dp[i-1])
                dp[i]=0;
                // 如果亏损比昨天赚的利润小一些,说明今天卖掉还是能赚点钱的,虽然不如昨天卖赚的多
                else
                dp[i]=dp[i-1]-(prices[i-1]-prices[i]);
            }
        }
        // 找到最大值并返回
        int max=0;
        for(int i=0;i<len;i++)
        if(dp[i]>max) max=dp[i];
        return max;
    }
};

上一篇:服务器配置信息查看命令


下一篇:[Ubuntu] 查看 CPU 核数