题目地址:https://leetcode-cn.com/problems/gu-piao-de-zui-da-li-run-lcof/
题目描述
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
题目示例
示例 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。
解题思路
暴力法:选定初始值,然后用后面的每个数减去选定的值,从而遍历列举所有可能出现的结果,并进行比较,但此方法导致超时。
贪心方法:利用尾遍历方法寻找最大利润值。具体思路如下
- Step1:初始化prices数组中最大的价格为数组末尾元素值,当前利润curProfit和最大利润值均是0;
- Step2:循环计算当前利润curProfit值,若curProfit<0,则说明当前价格prices[i]更大,更新最大价格为当前价格,即maxPrice=prices[i],否则,我们对curProfit的值和maxProfit的值进行比较,若curProfit>maxProfit,则更新最大利润,即maxProfit=curProfit
- Step3:返回最大利润值maxProfit
动态规划:通过分析题目,我们定义两个变量maxProfit和loss,分别表示最大利润和亏损值,然后通过盈利状态转移方程maxProfit=max(maxProfit, prices[i]+loss)和亏损状态转移方程loss=max(loss, -prices[i])不断迭代更新,从而获得最大利润值maxProfit。
程序源码
暴力法(导致超时)
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() < 2) return 0; //股票交易不满两天
int maxProfit = 0;
for(int i = 0; i < prices.size(); i++)
{
for(int j = i + 1; j < prices.size(); j++)
{
int curProfit = prices[j] - prices[i];
if(curProfit > maxProfit)
{
maxProfit = curProfit;
}
}
}
return maxProfit;
}
};
贪心策略
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size() < 2) return 0; //股票交易不满两天
int maxPrice = prices[prices.size() - 1] ;
int curProfit = 0;
int maxProfit = 0;
for(int i = prices.size() - 1; i >= 0; i--)
{
curProfit = maxPrice - prices[i];
if(curProfit <= 0)
maxPrice = prices[i];
else
{
if(curProfit > maxProfit)
maxProfit = curProfit;
}
}
return maxProfit;
}
};
动态规划
class Solution { public: int maxProfit(vector<int>& prices) { if(prices.size() < 2) return 0; //股票交易不满两天 int maxProfit = 0, loss = -prices[0]; for(int i=1; i < prices.size(); i++) { maxProfit = max(maxProfit, prices[i] + loss); //盈利状态转移方程 loss = max(loss, -prices[i]); //亏损状态转移方程 } return maxProfit; } };