题目描述:
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例 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;
}
};