面试题63. 股票的最大利润

这个题和买股票的最佳时机一模一样,所以题目和示例就不再陈述,这篇主要说一下动态规划解决这个问题。前面我们使用暴力法和滑动窗口的方式解决了这个问题,但是最好的思路是动态规划。

这个题目很简单,但是对我们理解动态规划很有帮助,碰到最优问题,或者是结果数组存在某些联系的问题,我们最应该先想到动态规划,因为它的本质是:

  1. 求解最优结果,每次的最优结果通过状态转移方程不断计算得到。
  2. 借助辅助空间,将每次的结果记忆化,降低时间复杂度。

那我们就看一下这个题目如何使用动态规划,首先考虑用数组状态,定义状态转移方程,是否可以优化空间:

  1. 我们需要先选择一个最小的买入点,c=min(price[i],c)
  2. 我们需要得到最大的利润,一个买出点存在多个利润,但我们需要最大的,所以我们用数组dp[i]保存第 i 天的最大利润。
  3. 状态转移方程:就是思考如何用前一次的结果推导出现在的。那么第 i 天的利润是prices[i]-c,如果它小于dp[i-1],表示第i-1天的利润更大,那么第i天的利润就是dp[i-1]。所以dp[i]=max(dp[i]-c,dp[i-1])。
  4. 最后返回dp[i]即可,即到最后一天的最大利润。

我们先用示例看一下过程:示例:输入: [7,1,5,3,6,4] 输出: 5

在这里插入图片描述
那我们可以明显的看到dp[i]的结果,只和dp[i-1],c有关,那么尝试去优化dp。
因为dp[i-1]每次保存的都是最大值,所以那么我们可以用一个变量代替dp[i-1],我们定义为pro,pro=max(pro,dp[i]-c),这也是优化后的转移方程,那么这个代码就很简单:

int maxProfit(vector<int>& prices) 
{
	if(!(prices.empty()))
	{
		int c=prices[0];//定义初始买入点
		int pro=INT_MIN;//初始利润最大值
		for(int i=0;i<prices.size();i++)
		{
			c=min(c,prices[i]);
			pro=max(pro,prices[i]-c);
		}
		return pro;
	}
	return 0;
	
}

其实写完代码,发现和滑动窗口的代码还挺像的,但是这两个思路还是有很大差异的,都是很重要的。

加油哦!💪。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值